diff options
Diffstat (limited to 'FreeRTOS/Test/CBMC')
173 files changed, 9503 insertions, 0 deletions
diff --git a/FreeRTOS/Test/CBMC/.gitignore b/FreeRTOS/Test/CBMC/.gitignore new file mode 100644 index 000000000..225be8104 --- /dev/null +++ b/FreeRTOS/Test/CBMC/.gitignore @@ -0,0 +1,5 @@ +cbmc.txt +property.xml +coverage.xml +*.goto +**/html/*
\ No newline at end of file diff --git a/FreeRTOS/Test/CBMC/README.md b/FreeRTOS/Test/CBMC/README.md new file mode 100644 index 000000000..09d5e1481 --- /dev/null +++ b/FreeRTOS/Test/CBMC/README.md @@ -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. diff --git a/FreeRTOS/Test/CBMC/cmake/compute-coverage.cmake b/FreeRTOS/Test/CBMC/cmake/compute-coverage.cmake new file mode 100644 index 000000000..819fa11bb --- /dev/null +++ b/FreeRTOS/Test/CBMC/cmake/compute-coverage.cmake @@ -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() diff --git a/FreeRTOS/Test/CBMC/cmake/compute-property.cmake b/FreeRTOS/Test/CBMC/cmake/compute-property.cmake new file mode 100644 index 000000000..3192aa99a --- /dev/null +++ b/FreeRTOS/Test/CBMC/cmake/compute-property.cmake @@ -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() diff --git a/FreeRTOS/Test/CBMC/cmake/model-check.cmake b/FreeRTOS/Test/CBMC/cmake/model-check.cmake new file mode 100644 index 000000000..8dc37b094 --- /dev/null +++ b/FreeRTOS/Test/CBMC/cmake/model-check.cmake @@ -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() diff --git a/FreeRTOS/Test/CBMC/include/README.md b/FreeRTOS/Test/CBMC/include/README.md new file mode 100644 index 000000000..fa317dc04 --- /dev/null +++ b/FreeRTOS/Test/CBMC/include/README.md @@ -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 diff --git a/FreeRTOS/Test/CBMC/include/aws_freertos_ip_verification_access_ip_define.h b/FreeRTOS/Test/CBMC/include/aws_freertos_ip_verification_access_ip_define.h new file mode 100644 index 000000000..22434a91c --- /dev/null +++ b/FreeRTOS/Test/CBMC/include/aws_freertos_ip_verification_access_ip_define.h @@ -0,0 +1,3 @@ +eFrameProcessingResult_t publicProcessIPPacket( IPPacket_t * const pxIPPacket, NetworkBufferDescriptor_t * const pxNetworkBuffer ) { + prvProcessIPPacket(pxIPPacket, pxNetworkBuffer); +} diff --git a/FreeRTOS/Test/CBMC/include/aws_freertos_tcp_verification_access_tcp_define.h b/FreeRTOS/Test/CBMC/include/aws_freertos_tcp_verification_access_tcp_define.h new file mode 100644 index 000000000..01075d2ba --- /dev/null +++ b/FreeRTOS/Test/CBMC/include/aws_freertos_tcp_verification_access_tcp_define.h @@ -0,0 +1,12 @@ +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 ); +} diff --git a/FreeRTOS/Test/CBMC/include/cbmc.h b/FreeRTOS/Test/CBMC/include/cbmc.h new file mode 100644 index 000000000..c30063bae --- /dev/null +++ b/FreeRTOS/Test/CBMC/include/cbmc.h @@ -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 ); +} diff --git a/FreeRTOS/Test/CBMC/include/queue_init.h b/FreeRTOS/Test/CBMC/include/queue_init.h new file mode 100644 index 000000000..f05d18830 --- /dev/null +++ b/FreeRTOS/Test/CBMC/include/queue_init.h @@ -0,0 +1,141 @@ +#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 sepearted 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 + +/* 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(); + 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 + +/* 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(); + 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(); + 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(); + 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; +} diff --git a/FreeRTOS/Test/CBMC/include/tasksStubs.h b/FreeRTOS/Test/CBMC/include/tasksStubs.h new file mode 100644 index 000000000..a0dd6de4a --- /dev/null +++ b/FreeRTOS/Test/CBMC/include/tasksStubs.h @@ -0,0 +1,10 @@ +#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 */ diff --git a/FreeRTOS/Test/CBMC/patches/.gitattributes b/FreeRTOS/Test/CBMC/patches/.gitattributes new file mode 100644 index 000000000..a41fc7b45 --- /dev/null +++ b/FreeRTOS/Test/CBMC/patches/.gitattributes @@ -0,0 +1,2 @@ +# It seems git apply does not want crlf line endings on Windows +*.patch eol=lf diff --git a/FreeRTOS/Test/CBMC/patches/.gitignore b/FreeRTOS/Test/CBMC/patches/.gitignore new file mode 100644 index 000000000..4dec98ff0 --- /dev/null +++ b/FreeRTOS/Test/CBMC/patches/.gitignore @@ -0,0 +1,2 @@ +auto_patch* +patched diff --git a/FreeRTOS/Test/CBMC/patches/0005-Remove-volatile-qualifier-from-tasks-variables.patch b/FreeRTOS/Test/CBMC/patches/0005-Remove-volatile-qualifier-from-tasks-variables.patch new file mode 100644 index 000000000..29cde0e77 --- /dev/null +++ b/FreeRTOS/Test/CBMC/patches/0005-Remove-volatile-qualifier-from-tasks-variables.patch @@ -0,0 +1,79 @@ +This patch removes the volatile qualifier from some global variable +declarations in the tasks.c file. For task pool proofs, we are running +`goto-instrument` with the `--nondet-volatile` flag on, which causes reads from +volatile variable to be nondeterministic (i.e., any possible value can be +returned). This is actually the desired behavior for volatile variables +regarding verification purposes. However, this causes a lot of trouble when +such variables are pointers, since one of the possible values we can get when +dereferencing a volatile pointer is `NULL`. + +In the case of `uxPendedTicks`, a non-volatile copy of the variable is done +before the following loop in tasks.c (lines 2231-2255): + +{ + UBaseType_t uxPendedCounts = uxPendedTicks; /* Non-volatile copy. */ + + if( uxPendedCounts > ( UBaseType_t ) 0U ) + { + do + { + if( xTaskIncrementTick() != pdFALSE ) + { + xYieldPending = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + --uxPendedCounts; + } while( uxPendedCounts > ( UBaseType_t ) 0U ); + + uxPendedTicks = 0; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } +} + +Here, `uxPendedTicks` could return any value, making it impossible to unwind +(or unroll) this loop in CBMC. Therefore, we require `uxPendedTicks` to behave +as a regular variable so that the loop can be unwound. + +--- +diff --git a/FreeRTOS/Source/tasks.c b/FreeRTOS/Source/tasks.c +index ff657733..8b57d198 100644 +--- a/FreeRTOS/Source/tasks.c ++++ b/FreeRTOS/Source/tasks.c +@@ -331,7 +331,7 @@ typedef tskTCB TCB_t; + + /*lint -save -e956 A manual analysis and inspection has been used to determine + which static variables must be declared volatile. */ +-PRIVILEGED_DATA TCB_t * volatile pxCurrentTCB = NULL; ++PRIVILEGED_DATA TCB_t * pxCurrentTCB = NULL; + + /* Lists for ready and blocked tasks. -------------------- + xDelayedTaskList1 and xDelayedTaskList2 could be move to function scople but +@@ -340,8 +340,8 @@ the static qualifier. */ + PRIVILEGED_DATA static List_t pxReadyTasksLists[ configMAX_PRIORITIES ];/*< Prioritised ready tasks. */ + PRIVILEGED_DATA static List_t xDelayedTaskList1; /*< Delayed tasks. */ + PRIVILEGED_DATA static List_t xDelayedTaskList2; /*< Delayed tasks (two lists are used - one for delays that have overflowed the current tick count. */ +-PRIVILEGED_DATA static List_t * volatile pxDelayedTaskList; /*< Points to the delayed task list currently being used. */ +-PRIVILEGED_DATA static List_t * volatile pxOverflowDelayedTaskList; /*< Points to the delayed task list currently being used to hold tasks that have overflowed the current tick count. */ ++PRIVILEGED_DATA static List_t * pxDelayedTaskList; /*< Points to the delayed task list currently being used. */ ++PRIVILEGED_DATA static List_t * pxOverflowDelayedTaskList; /*< Points to the delayed task list currently being used to hold tasks that have overflowed the current tick count. */ + PRIVILEGED_DATA static List_t xPendingReadyList; /*< Tasks that have been readied while the scheduler was suspended. They will be moved to the ready list when the scheduler is resumed. */ + + #if( INCLUDE_vTaskDelete == 1 ) +@@ -368,10 +368,10 @@ PRIVILEGED_DATA static volatile UBaseType_t uxCurrentNumberOfTasks = ( UBaseTyp + + /* Other file private variables. --------------------------------*/ + PRIVILEGED_DATA static volatile UBaseType_t uxCurrentNumberOfTasks = ( UBaseType_t ) 0U; + PRIVILEGED_DATA static volatile TickType_t xTickCount = ( TickType_t ) configINITIAL_TICK_COUNT; + PRIVILEGED_DATA static volatile UBaseType_t uxTopReadyPriority = tskIDLE_PRIORITY; + PRIVILEGED_DATA static volatile BaseType_t xSchedulerRunning = pdFALSE; +-PRIVILEGED_DATA static volatile TickType_t xPendedTicks = ( TickType_t ) 0U; ++PRIVILEGED_DATA static TickType_t xPendedTicks = ( TickType_t ) 0U; + PRIVILEGED_DATA static volatile BaseType_t xYieldPending = pdFALSE; + PRIVILEGED_DATA static volatile BaseType_t xNumOfOverflows = ( BaseType_t ) 0; + PRIVILEGED_DATA static UBaseType_t uxTaskNumber = ( UBaseType_t ) 0U; diff --git a/FreeRTOS/Test/CBMC/patches/0005-remove-static-from-prvCopyDataToQueue.patch b/FreeRTOS/Test/CBMC/patches/0005-remove-static-from-prvCopyDataToQueue.patch new file mode 100644 index 000000000..5a79ae8cd --- /dev/null +++ b/FreeRTOS/Test/CBMC/patches/0005-remove-static-from-prvCopyDataToQueue.patch @@ -0,0 +1,22 @@ +diff --git a/FreeRTOS/Source/queue.c b/FreeRTOS/Source/queue.c +index df2b9c8c..c2265c26 100644 +--- a/FreeRTOS/Source/queue.c ++++ b/FreeRTOS/Source/queue.c +@@ -105,7 +105,7 @@ static BaseType_t prvIsQueueFull( const Queue_t *pxQueue ) PRIVILEGED_FUNCTION; + * Copies an item into the queue, either at the front of the queue or the + * back of the queue. + */ +-static BaseType_t prvCopyDataToQueue( Queue_t * const pxQueue, const void *pvItemToQueue, const BaseType_t xPosition ) PRIVILEGED_FUNCTION; ++BaseType_t prvCopyDataToQueue( Queue_t * const pxQueue, const void *pvItemToQueue, const BaseType_t xPosition ) PRIVILEGED_FUNCTION; + + /* + * Copies an item out of a queue. +@@ -1985,7 +1985,7 @@ Queue_t * const pxQueue = xQueue; + #endif /* configUSE_MUTEXES */ + /*-----------------------------------------------------------*/ + +-static BaseType_t prvCopyDataToQueue( Queue_t * const pxQueue, const void *pvItemToQueue, const BaseType_t xPosition ) ++BaseType_t prvCopyDataToQueue( Queue_t * const pxQueue, const void *pvItemToQueue, const BaseType_t xPosition ) + { + BaseType_t xReturn = pdFALSE; + UBaseType_t uxMessagesWaiting; diff --git a/FreeRTOS/Test/CBMC/patches/0006-Remove-static-from-prvNotifyQueueSetContainer.patch b/FreeRTOS/Test/CBMC/patches/0006-Remove-static-from-prvNotifyQueueSetContainer.patch new file mode 100644 index 000000000..9cbe7cf5f --- /dev/null +++ b/FreeRTOS/Test/CBMC/patches/0006-Remove-static-from-prvNotifyQueueSetContainer.patch @@ -0,0 +1,22 @@ +diff --git a/FreeRTOS/Source/queue.c b/FreeRTOS/Source/queue.c +index 17a6964e..24a40c29 100644 +--- a/FreeRTOS/Source/queue.c ++++ b/FreeRTOS/Source/queue.c +@@ -207,7 +207,7 @@ static void prvCopyDataFromQueue( Queue_t * const pxQueue, void * const pvBuffer + * Checks to see if a queue is a member of a queue set, and if so, notifies + * the queue set that the queue contains data. + */ +- static BaseType_t prvNotifyQueueSetContainer( const Queue_t * const pxQueue ) PRIVILEGED_FUNCTION; ++ BaseType_t prvNotifyQueueSetContainer( const Queue_t * const pxQueue ) PRIVILEGED_FUNCTION; + #endif + + /* +@@ -2887,7 +2887,7 @@ Queue_t * const pxQueue = xQueue; + + #if ( configUSE_QUEUE_SETS == 1 ) + +- static BaseType_t prvNotifyQueueSetContainer( const Queue_t * const pxQueue ) ++ BaseType_t prvNotifyQueueSetContainer( const Queue_t * const pxQueue ) + { + Queue_t *pxQueueSetContainer = pxQueue->pxQueueSetContainer; + BaseType_t xReturn = pdFALSE; diff --git a/FreeRTOS/Test/CBMC/patches/0007-Remove-static-from-prvUnlockQueue.patch b/FreeRTOS/Test/CBMC/patches/0007-Remove-static-from-prvUnlockQueue.patch new file mode 100644 index 000000000..eaae401c6 --- /dev/null +++ b/FreeRTOS/Test/CBMC/patches/0007-Remove-static-from-prvUnlockQueue.patch @@ -0,0 +1,22 @@ +diff --git a/FreeRTOS/Source/queue.c b/FreeRTOS/Source/queue.c +index 17a6964e..60ea3e69 100644 +--- a/FreeRTOS/Source/queue.c ++++ b/FreeRTOS/Source/queue.c +@@ -175,7 +175,7 @@ typedef xQUEUE Queue_t; + * to indicate that a task may require unblocking. When the queue in unlocked + * these lock counts are inspected, and the appropriate action taken. + */ +-static void prvUnlockQueue( Queue_t * const pxQueue ) PRIVILEGED_FUNCTION; ++void prvUnlockQueue( Queue_t * const pxQueue ) PRIVILEGED_FUNCTION; + + /* + * Uses a critical section to determine if there is any data in a queue. +@@ -2175,7 +2175,7 @@ static void prvCopyDataFromQueue( Queue_t * const pxQueue, void * const pvBuffer + } + /*-----------------------------------------------------------*/ + +-static void prvUnlockQueue( Queue_t * const pxQueue ) ++void prvUnlockQueue( Queue_t * const pxQueue ) + { + /* THIS FUNCTION MUST BE CALLED WITH THE SCHEDULER SUSPENDED. */ + diff --git a/FreeRTOS/Test/CBMC/patches/FreeRTOSConfig.h b/FreeRTOS/Test/CBMC/patches/FreeRTOSConfig.h new file mode 100644 index 000000000..28de2bd15 --- /dev/null +++ b/FreeRTOS/Test/CBMC/patches/FreeRTOSConfig.h @@ -0,0 +1,237 @@ +/* + * FreeRTOS Kernel V10.0.1 + * Copyright (C) 2017 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 ) +#define configUSE_16_BIT_TICKS 0 +#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 generater 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 */ diff --git a/FreeRTOS/Test/CBMC/patches/FreeRTOSIPConfig.h b/FreeRTOS/Test/CBMC/patches/FreeRTOSIPConfig.h new file mode 100644 index 000000000..5e9180f8e --- /dev/null +++ b/FreeRTOS/Test/CBMC/patches/FreeRTOSIPConfig.h @@ -0,0 +1,307 @@ +/* +FreeRTOS Kernel V10.2.0 +Copyright (C) 2017 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. */ +#define ipconfigHAS_DEBUG_PRINTF 0 +#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. */ +#define ipconfigBYTE_ORDER pdFREERTOS_LITTLE_ENDIAN + +/* 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. */ +#define ipconfigUSE_DNS_CACHE ( 1 ) +#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. */ +#define ipconfigARP_CACHE_ENTRIES 6 + +/* 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. */ +#define ipconfigALLOW_SOCKET_SEND_WITHOUT_BIND 1 + +/* 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. */ +#define ipconfigUSE_TCP ( 1 ) + +/* USE_WIN: Let TCP use windowing mechanism. */ +#define ipconfigUSE_TCP_WIN ( 1 ) + +/* 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 1200U + +/* 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. */ +#define ipconfigSUPPORT_OUTGOING_PINGS 0 + +/* If ipconfigSUPPORT_SELECT_FUNCTION is set to 1 then the FreeRTOS_select() + * (and associated) API function is available. */ +#define ipconfigSUPPORT_SELECT_FUNCTION 0 + +/* 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. */ +#define ipconfigSOCKET_HAS_USER_SEMAPHORE ( 0 ) + +#define ipconfigSOCKET_HAS_USER_WAKE_CALLBACK ( 1 ) +#define ipconfigUSE_CALLBACKS ( 0 ) + + +#define portINLINE __inline + +void vApplicationMQTTGetKeys( const char ** ppcRootCA, + const char ** ppcClientCert, + const char ** ppcClientPrivateKey ); + +#endif /* FREERTOS_IP_CONFIG_H */ diff --git a/FreeRTOS/Test/CBMC/patches/Makefile b/FreeRTOS/Test/CBMC/patches/Makefile new file mode 100644 index 000000000..27888e63b --- /dev/null +++ b/FreeRTOS/Test/CBMC/patches/Makefile @@ -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 diff --git a/FreeRTOS/Test/CBMC/patches/README.md b/FreeRTOS/Test/CBMC/patches/README.md new file mode 100644 index 000000000..ec0e5d424 --- /dev/null +++ b/FreeRTOS/Test/CBMC/patches/README.md @@ -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.
\ No newline at end of file diff --git a/FreeRTOS/Test/CBMC/patches/__init__.py b/FreeRTOS/Test/CBMC/patches/__init__.py new file mode 100755 index 000000000..e69de29bb --- /dev/null +++ b/FreeRTOS/Test/CBMC/patches/__init__.py diff --git a/FreeRTOS/Test/CBMC/patches/compute_patch.py b/FreeRTOS/Test/CBMC/patches/compute_patch.py new file mode 100755 index 000000000..3e854177c --- /dev/null +++ b/FreeRTOS/Test/CBMC/patches/compute_patch.py @@ -0,0 +1,241 @@ +#!/usr/bin/env python3 +# +# Generation of patches for CBMC proofs. +# +# Copyright (C) 2019 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) diff --git a/FreeRTOS/Test/CBMC/patches/patch.py b/FreeRTOS/Test/CBMC/patches/patch.py new file mode 100755 index 000000000..c2c0883a3 --- /dev/null +++ b/FreeRTOS/Test/CBMC/patches/patch.py @@ -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() diff --git a/FreeRTOS/Test/CBMC/patches/patches_constants.py b/FreeRTOS/Test/CBMC/patches/patches_constants.py new file mode 100755 index 000000000..71f0b0537 --- /dev/null +++ b/FreeRTOS/Test/CBMC/patches/patches_constants.py @@ -0,0 +1,42 @@ +#!/usr/bin/env python3 +# +# Constants for the generation of patches for CBMC proofs. +# +# Copyright (C) 2019 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 = [ + "..", "..", "..", "Source", "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")] diff --git a/FreeRTOS/Test/CBMC/patches/unpatch.py b/FreeRTOS/Test/CBMC/patches/unpatch.py new file mode 100755 index 000000000..2162971fd --- /dev/null +++ b/FreeRTOS/Test/CBMC/patches/unpatch.py @@ -0,0 +1,42 @@ +#!/usr/bin/env python3 +# +# unpatching changes for the CBMC proofs. +# +# Copyright (C) 2019 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)) diff --git a/FreeRTOS/Test/CBMC/proofs/.gitignore b/FreeRTOS/Test/CBMC/proofs/.gitignore new file mode 100644 index 000000000..3498c4b3b --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/.gitignore @@ -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 diff --git a/FreeRTOS/Test/CBMC/proofs/CBMCStubLibrary/tasksStubs.c b/FreeRTOS/Test/CBMC/proofs/CBMCStubLibrary/tasksStubs.c new file mode 100644 index 000000000..3fe245f80 --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/CBMCStubLibrary/tasksStubs.c @@ -0,0 +1,47 @@ +#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 overwritting 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(); + } +} diff --git a/FreeRTOS/Test/CBMC/proofs/CMakeLists.txt b/FreeRTOS/Test/CBMC/proofs/CMakeLists.txt new file mode 100644 index 000000000..aaa2e3c8a --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/CMakeLists.txt @@ -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 +) + diff --git a/FreeRTOS/Test/CBMC/proofs/Makefile.template b/FreeRTOS/Test/CBMC/proofs/Makefile.template new file mode 100644 index 000000000..0e47abe4d --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Makefile.template @@ -0,0 +1,160 @@ +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 = \ + $(CBMCFLAGS2) \ + $(C_CBMCFLAGS) $(O_CBMCFLAGS) $(H_CBMCFLAGS) \ + # empty + +INSTFLAGS = \ + $(INSTFLAGS2) \ + $(C_INSTFLAGS) $(O_INSTFLAGS) $(H_INSTFLAGS) \ + # empty + +# ____________________________________________________________________ +# Rules +# +# Rules for building a:FR object files. These are not harness-specific, +# and several harnesses might depend on a particular a:FR object, so +# define them all once here. + +@RULE_GOTO@ + $(GOTO_CC) @COMPILE_ONLY@ @RULE_OUTPUT@ $(INC) $(CFLAGS) @RULE_INPUT@ + +# ____________________________________________________________________ +# Rules +# +# Rules for patching + +patch: + cd $(PROOFS)/../patches && ./patch.py + +unpatch: + cd $(PROOFS)/../patches && ./unpatch.py + +# ____________________________________________________________________ +# Rules +# +# Rules for building the CBMC harness + +queue_datastructure.h: $(H_OBJS_EXCEPT_HARNESS) + python3 @TYPE_HEADER_SCRIPT@ --binary $(FREERTOS)/Source/queue.goto --c-file $(FREERTOS)/Source/queue.c + +$(ENTRY)_harness.goto: $(ENTRY)_harness.c $(H_GENERATE_HEADER) + $(GOTO_CC) @COMPILE_ONLY@ @RULE_OUTPUT@ $(INC) $(CFLAGS) @RULE_INPUT@ + +$(ENTRY)1.goto: $(OBJS) + $(GOTO_CC) @COMPILE_LINK@ @RULE_OUTPUT@ --function harness $(OBJS) + +$(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) patch + $(MAKE) $(ENTRY).goto + +cbmc.txt: $(ENTRY).goto + - cbmc $(CBMCFLAGS) --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) \ + --blddir $(FREERTOS) \ + --htmldir html \ + --srcexclude "(.@FORWARD_SLASH@Demo)" \ + --result cbmc.txt \ + --property property.xml \ + --block coverage.xml + +# ____________________________________________________________________ +# 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 + +distclean: veryclean + cd $(PROOFS)/../patches && ./unpatch.py + cd $(PROOFS) && ./make-remove-makefiles.py diff --git a/FreeRTOS/Test/CBMC/proofs/MakefileCommon.json b/FreeRTOS/Test/CBMC/proofs/MakefileCommon.json new file mode 100644 index 000000000..c7495bf29 --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/MakefileCommon.json @@ -0,0 +1,46 @@ +{ + "FREERTOS": [ " ../../.." ], + "PROOFS": [ "." ], + + "DEF ": [ + "_DEBUG", + "__free_rtos__", + "_CONSOLE", + "_WIN32_WINNT=0x0500", + "WINVER=0x400", + "_CRT_SECURE_NO_WARNINGS", + "__PRETTY_FUNCTION__=__FUNCTION__", + "CBMC", + "'configASSERT(X)=__CPROVER_assert(X,\"Assertion Error\")'", + "'configPRECONDITION(X)=__CPROVER_assume(X)'", + "'_static='", + "'_volatile='" + ], + + "INC ": [ + "$(FREERTOS)/Source/include", + "$(FREERTOS)/Source/portable/MSVC-MingW", + "$(FREERTOS)/../FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include", + "$(FREERTOS)/../FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/Compiler/MSVC", + "$(FREERTOS)/../FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/WinPCap", + "$(FREERTOS)/Demo/Common/include", + "$(FREERTOS)/Test/CBMC/include", + "$(FREERTOS)/Test/CBMC/patches", + "$(FREERTOS)/../FreeRTOS-Plus/Test/CBMC/windows", + "$(FREERTOS)/../FreeRTOS-Plus/Test/CBMC/windows2" + ], + + "CBMCFLAGS ": [ + "--object-bits 7", + "--32", + "--bounds-check", + "--pointer-check" + ], + + "FORWARD_SLASH": ["/"], + + "TYPE_HEADERS": [ + "$(FREERTOS)/Source/queue.c" + ] +} + diff --git a/FreeRTOS/Test/CBMC/proofs/MakefileLinux.json b/FreeRTOS/Test/CBMC/proofs/MakefileLinux.json new file mode 100644 index 000000000..08442a2ab --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/MakefileLinux.json @@ -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" + ] +} diff --git a/FreeRTOS/Test/CBMC/proofs/MakefileWindows.json b/FreeRTOS/Test/CBMC/proofs/MakefileWindows.json new file mode 100644 index 000000000..543dd6219 --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/MakefileWindows.json @@ -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" + ] +} diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/QueueCreateCountingSemaphore/Makefile.json b/FreeRTOS/Test/CBMC/proofs/Queue/QueueCreateCountingSemaphore/Makefile.json new file mode 100644 index 000000000..4e26b37f8 --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Queue/QueueCreateCountingSemaphore/Makefile.json @@ -0,0 +1,47 @@ +# +# FreeRTOS memory safety proofs with CBMC. +# Copyright (C) 2019 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": "QueueCreateCountingSemaphore", + "CBMCFLAGS": [ + "--unwind 1", + "--signed-overflow-check", + "--pointer-overflow-check", + "--unsigned-overflow-check" + ], + "OBJS": [ + "$(ENTRY)_harness.goto", + "$(FREERTOS)/Source/queue.goto", + "$(FREERTOS)/Source/list.goto" + ], + "DEF": [ + "configUSE_TRACE_FACILITY=0", + "configGENERATE_RUN_TIME_STATS=0" + ] +} + diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/QueueCreateCountingSemaphore/QueueCreateCountingSemaphore_harness.c b/FreeRTOS/Test/CBMC/proofs/Queue/QueueCreateCountingSemaphore/QueueCreateCountingSemaphore_harness.c new file mode 100644 index 000000000..f079ecbdf --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Queue/QueueCreateCountingSemaphore/QueueCreateCountingSemaphore_harness.c @@ -0,0 +1,44 @@ +/* + * FreeRTOS memory safety proofs with CBMC. + * Copyright (C) 2019 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 "FreeRTOS.h" +#include "queue.h" + +#include "cbmc.h" + + +void harness(){ + UBaseType_t uxMaxCount; + UBaseType_t uxInitialCount; + + __CPROVER_assume(uxMaxCount != 0); + __CPROVER_assume(uxInitialCount <= uxMaxCount); + + xQueueCreateCountingSemaphore( uxMaxCount, uxInitialCount ); +} + diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/QueueCreateCountingSemaphore/README.md b/FreeRTOS/Test/CBMC/proofs/Queue/QueueCreateCountingSemaphore/README.md new file mode 100644 index 000000000..b01b0cfa6 --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Queue/QueueCreateCountingSemaphore/README.md @@ -0,0 +1,10 @@ +Assuming uxMaxCount != 0 and uxInitialCount <= uxMaxCount, +this harness proves the memory safety of QueueCreateCountingSemaphore. + +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 diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/QueueCreateCountingSemaphoreStatic/Makefile.json b/FreeRTOS/Test/CBMC/proofs/Queue/QueueCreateCountingSemaphoreStatic/Makefile.json new file mode 100644 index 000000000..d9a9a8ec8 --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Queue/QueueCreateCountingSemaphoreStatic/Makefile.json @@ -0,0 +1,50 @@ +# +# FreeRTOS memory safety proofs with CBMC. +# Copyright (C) 2019 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": "QueueCreateCountingSemaphoreStatic", + "CBMCFLAGS": [ + "--unwind 1", + "--signed-overflow-check", + "--pointer-overflow-check", + "--unsigned-overflow-check" + ], + "OBJS": [ + "$(ENTRY)_harness.goto", + "$(FREERTOS)/Source/queue.goto", + "$(FREERTOS)/Source/list.goto" + ], + "DEF": [ + "configUSE_TRACE_FACILITY=0", + "configGENERATE_RUN_TIME_STATS=0" + ], + "GENERATE_HEADER": [ + "queue_datastructure.h" + ] +} + diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/QueueCreateCountingSemaphoreStatic/QueueCreateCountingSemaphoreStatic_harness.c b/FreeRTOS/Test/CBMC/proofs/Queue/QueueCreateCountingSemaphoreStatic/QueueCreateCountingSemaphoreStatic_harness.c new file mode 100644 index 000000000..cb09c72b9 --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Queue/QueueCreateCountingSemaphoreStatic/QueueCreateCountingSemaphoreStatic_harness.c @@ -0,0 +1,45 @@ +/* + * FreeRTOS memory safety proofs with CBMC. + * Copyright (C) 2019 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 "FreeRTOS.h" +#include "queue.h" +#include "cbmc.h" + + +void harness(){ + UBaseType_t uxMaxCount; + UBaseType_t uxInitialCount; + + //xStaticQueue is required to be not null + StaticQueue_t xStaticQueue; + + //Checked invariant + __CPROVER_assume(uxMaxCount != 0); + __CPROVER_assume(uxInitialCount <= uxMaxCount); + xQueueCreateCountingSemaphoreStatic( uxMaxCount, uxInitialCount, &xStaticQueue ); +} diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/QueueCreateCountingSemaphoreStatic/README.md b/FreeRTOS/Test/CBMC/proofs/Queue/QueueCreateCountingSemaphoreStatic/README.md new file mode 100644 index 000000000..c6103de51 --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Queue/QueueCreateCountingSemaphoreStatic/README.md @@ -0,0 +1,11 @@ +Assuming uxMaxCount > 0, uxInitialCount <= uxMaxCount and the reference +to the storage area is not null, +this harness proves the memory saftey of QueueCreateCountingSemphoreStatic. + +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 diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/QueueCreateMutex/Makefile.json b/FreeRTOS/Test/CBMC/proofs/Queue/QueueCreateMutex/Makefile.json new file mode 100644 index 000000000..6409cd15a --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Queue/QueueCreateMutex/Makefile.json @@ -0,0 +1,47 @@ +# +# FreeRTOS memory safety proofs with CBMC. +# Copyright (C) 2019 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": "QueueCreateMutex", + "CBMCFLAGS": [ + "--unwind 1", + "--signed-overflow-check", + "--pointer-overflow-check", + "--unsigned-overflow-check" + ], + "OBJS": [ + "$(ENTRY)_harness.goto", + "$(FREERTOS)/Source/queue.goto", + "$(FREERTOS)/Source/list.goto" + ], + "DEF": [ + "configUSE_TRACE_FACILITY=0", + "configGENERATE_RUN_TIME_STATS=0" + ] +} + diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/QueueCreateMutex/QueueCreateMutex_harness.c b/FreeRTOS/Test/CBMC/proofs/Queue/QueueCreateMutex/QueueCreateMutex_harness.c new file mode 100644 index 000000000..3528d9640 --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Queue/QueueCreateMutex/QueueCreateMutex_harness.c @@ -0,0 +1,38 @@ +/* + * FreeRTOS memory safety proofs with CBMC. + * Copyright (C) 2019 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 "FreeRTOS.h" +#include "queue.h" + +#include "cbmc.h" + +void harness() { + uint8_t ucQueueType; + + xQueueCreateMutex(ucQueueType); +} diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/QueueCreateMutex/README.md b/FreeRTOS/Test/CBMC/proofs/Queue/QueueCreateMutex/README.md new file mode 100644 index 000000000..7c73daf04 --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Queue/QueueCreateMutex/README.md @@ -0,0 +1,14 @@ +This harness proves the memory safety of QueueCreateMutex +for totally unconstrained input. + +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 +* xTaskGetSchedulerState +* xTaskPriorityDisinherit +* xTaskRemoveFromEventList diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/QueueCreateMutexStatic/Makefile.json b/FreeRTOS/Test/CBMC/proofs/Queue/QueueCreateMutexStatic/Makefile.json new file mode 100644 index 000000000..7de7e05dc --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Queue/QueueCreateMutexStatic/Makefile.json @@ -0,0 +1,50 @@ +# +# FreeRTOS memory safety proofs with CBMC. +# Copyright (C) 2019 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": "QueueCreateMutexStatic", + "CBMCFLAGS": [ + "--unwind 1", + "--signed-overflow-check", + "--pointer-overflow-check", + "--unsigned-overflow-check" + ], + "OBJS": [ + "$(ENTRY)_harness.goto", + "$(FREERTOS)/Source/queue.goto", + "$(FREERTOS)/Source/list.goto" + ], + "DEF": [ + "configUSE_TRACE_FACILITY=0", + "configGENERATE_RUN_TIME_STATS=0" + ], + "GENERATE_HEADER": [ + "queue_datastructure.h" + ] +} + diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/QueueCreateMutexStatic/QueueCreateMutexStatic_harness.c b/FreeRTOS/Test/CBMC/proofs/Queue/QueueCreateMutexStatic/QueueCreateMutexStatic_harness.c new file mode 100644 index 000000000..36848b6bf --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Queue/QueueCreateMutexStatic/QueueCreateMutexStatic_harness.c @@ -0,0 +1,41 @@ +/* + * FreeRTOS memory safety proofs with CBMC. + * Copyright (C) 2019 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 "FreeRTOS.h" +#include "queue.h" +#include "cbmc.h" + + +void harness(){ + uint8_t ucQueueType; + + //The mutex storage is assumed to be not null. + StaticQueue_t xStaticQueue; + + xQueueCreateMutexStatic( ucQueueType, &xStaticQueue ); +} diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/QueueCreateMutexStatic/README.md b/FreeRTOS/Test/CBMC/proofs/Queue/QueueCreateMutexStatic/README.md new file mode 100644 index 000000000..1e339f684 --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Queue/QueueCreateMutexStatic/README.md @@ -0,0 +1,15 @@ +Given that the passed mutex storage area is not null, the QueueCreateMutexStatic +function is memory safe. + +Otherwise an assertion violation is triggered. + +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 +* xTaskGetSchedulerState +* xTaskPriorityDisinherit diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/QueueGenericCreate/Configurations.json b/FreeRTOS/Test/CBMC/proofs/Queue/QueueGenericCreate/Configurations.json new file mode 100644 index 000000000..d7c4e86ed --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Queue/QueueGenericCreate/Configurations.json @@ -0,0 +1,110 @@ +# +# FreeRTOS memory safety proofs with CBMC. +# Copyright (C) 2019 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": "QueueGenericCreate", + + # A CBMC pointer is an object id followed by an offset into the object. + # The size of the offset is limited by the size of the object id. + "CBMC_OBJECT_BITS": "7", + "CBMC_OBJECT_MAX_SIZE": "\"((UINT32_MAX>>(CBMC_OBJECT_BITS+1))\"", + + "CBMCFLAGS": + [ + "--unwind 1", + "--signed-overflow-check", + "--pointer-overflow-check", + "--unsigned-overflow-check" + + ], + "OBJS": + [ + "$(ENTRY)_harness.goto", + "$(FREERTOS)/Source/list.goto", + "$(FREERTOS)/Source/queue.goto" + ], + "DEF": + [ + { + "QueueGenericCreate_default": [ + "CBMC_OBJECT_BITS={CBMC_OBJECT_BITS}", + "CBMC_OBJECT_MAX_SIZE={CBMC_OBJECT_MAX_SIZE}", + "configUSE_TRACE_FACILITY=0", + "configGENERATE_RUN_TIME_STATS=0", + "configUSE_MUTEXES=1", + "'mtCOVERAGE_TEST_MARKER()=__CPROVER_assert(1, \"Coverage marker\")'", + "configSUPPORT_STATIC_ALLOCATION=1", + "configUSE_QUEUE_SETS=0", + "configSUPPORT_DYNAMIC_ALLOCATION=1" + ] + }, + { + "QueueGenericCreate_noMutex": [ + "CBMC_OBJECT_BITS={CBMC_OBJECT_BITS}", + "CBMC_OBJECT_MAX_SIZE={CBMC_OBJECT_MAX_SIZE}", + "configUSE_TRACE_FACILITY=0", + "configGENERATE_RUN_TIME_STATS=0", + "configUSE_MUTEXES=0", + "configUSE_RECURSIVE_MUTEXES=0", + "'mtCOVERAGE_TEST_MARKER()=__CPROVER_assert(1, \"Coverage marker\")'", + "configSUPPORT_STATIC_ALLOCATION=1", + "configUSE_QUEUE_SETS=0", + "configSUPPORT_DYNAMIC_ALLOCATION=1" + ] + }, + { + "QueueGenericCreate_noSTATIC_ALLOCATION": [ + "CBMC_OBJECT_BITS={CBMC_OBJECT_BITS}", + "CBMC_OBJECT_MAX_SIZE={CBMC_OBJECT_MAX_SIZE}", + "configUSE_TRACE_FACILITY=0", + "configGENERATE_RUN_TIME_STATS=0", + "configUSE_MUTEXES=1", + "'mtCOVERAGE_TEST_MARKER()=__CPROVER_assert(1, \"Coverage marker\")'", + "configSUPPORT_STATIC_ALLOCATION=0", + "configUSE_QUEUE_SETS=0", + "configSUPPORT_DYNAMIC_ALLOCATION=1" + ] + }, + { + "QueueGenericCreate_useQueueSets": [ + "CBMC_OBJECT_BITS={CBMC_OBJECT_BITS}", + "CBMC_OBJECT_MAX_SIZE={CBMC_OBJECT_MAX_SIZE}", + "configUSE_TRACE_FACILITY=0", + "configGENERATE_RUN_TIME_STATS=0", + "configUSE_MUTEXES=1", + "'mtCOVERAGE_TEST_MARKER()=__CPROVER_assert(1, \"Coverage marker\")'", + "configSUPPORT_STATIC_ALLOCATION=1", + "configUSE_QUEUE_SETS=1", + "configSUPPORT_DYNAMIC_ALLOCATION=1" + ] + } + ], + "GENERATE_HEADER": [ + "queue_datastructure.h" + ] +} diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/QueueGenericCreate/QueueGenericCreate_harness.c b/FreeRTOS/Test/CBMC/proofs/Queue/QueueGenericCreate/QueueGenericCreate_harness.c new file mode 100644 index 000000000..4fa87f8d2 --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Queue/QueueGenericCreate/QueueGenericCreate_harness.c @@ -0,0 +1,50 @@ +/* + * FreeRTOS memory safety proofs with CBMC. + * Copyright (C) 2019 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 "FreeRTOS.h" +#include "queue.h" +#include "queue_datastructure.h" +#include "cbmc.h" + + +void harness(){ + UBaseType_t uxQueueLength; + UBaseType_t uxItemSize; + uint8_t ucQueueType; + + size_t uxQueueStorageSize; + __CPROVER_assume(uxQueueStorageSize < (UINT32_MAX>>8)); + + // QueueGenericCreate does not check for multiplication overflow + __CPROVER_assume(uxItemSize < uxQueueStorageSize/uxQueueLength); + + // QueueGenericCreate asserts positive queue length + __CPROVER_assume(uxQueueLength > ( UBaseType_t ) 0); + + xQueueGenericCreate( uxQueueLength, uxItemSize, ucQueueType ); +} diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/QueueGenericCreate/README.md b/FreeRTOS/Test/CBMC/proofs/Queue/QueueGenericCreate/README.md new file mode 100644 index 000000000..3b049bf3b --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Queue/QueueGenericCreate/README.md @@ -0,0 +1,13 @@ +The harness and configurations in this folder show memory safety of +QueueGenericCreate, given the assumption made in the harness. + +The principal assumption is that (uxItemSize * uxQueueLength) + sizeof(Queue_t) +does not overflow. + +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 diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/QueueGenericCreateStatic/Configurations.json b/FreeRTOS/Test/CBMC/proofs/Queue/QueueGenericCreateStatic/Configurations.json new file mode 100644 index 000000000..0acbc976e --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Queue/QueueGenericCreateStatic/Configurations.json @@ -0,0 +1,74 @@ +# +# FreeRTOS memory safety proofs with CBMC. +# Copyright (C) 2019 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": "QueueGenericCreateStatic", + + # A CBMC pointer is an object id followed by an offset into the object. + # The size of the offset is limited by the size of the object id. + "CBMC_OBJECT_BITS": "7", + "CBMC_OBJECT_MAX_SIZE": "\"((UINT32_MAX>>(CBMC_OBJECT_BITS+1))\"", + + "CBMCFLAGS": [ + "--unwind 1", + "--signed-overflow-check", + "--pointer-overflow-check", + "--unsigned-overflow-check" + ], + "OBJS": [ + "$(ENTRY)_harness.goto", + "$(FREERTOS)/Source/queue.goto", + "$(FREERTOS)/Source/list.goto" + ], + "DEF": [ + { + "QeueuGenericCreateStatic_DynamicAllocation": [ + "CBMC_OBJECT_BITS={CBMC_OBJECT_BITS}", + "CBMC_OBJECT_MAX_SIZE={CBMC_OBJECT_MAX_SIZE}", + "configUSE_TRACE_FACILITY=0", + "configGENERATE_RUN_TIME_STATS=0", + "configSUPPORT_STATIC_ALLOCATION=1", + "configSUPPORT_DYNAMIC_ALLOCATION=1" + ] + }, + { + "QeueuGenericCreateStatic_NoDynamicAllocation": [ + "CBMC_OBJECT_BITS={CBMC_OBJECT_BITS}", + "CBMC_OBJECT_MAX_SIZE={CBMC_OBJECT_MAX_SIZE}", + "configUSE_TRACE_FACILITY=0", + "configGENERATE_RUN_TIME_STATS=0", + "configSUPPORT_STATIC_ALLOCATION=1", + "configSUPPORT_DYNAMIC_ALLOCATION=0" + ] + } + ], + "GENERATE_HEADER": [ + "queue_datastructure.h" + ] +} + diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/QueueGenericCreateStatic/QueueGenericCreateStatic_harness.c b/FreeRTOS/Test/CBMC/proofs/Queue/QueueGenericCreateStatic/QueueGenericCreateStatic_harness.c new file mode 100644 index 000000000..553661cb2 --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Queue/QueueGenericCreateStatic/QueueGenericCreateStatic_harness.c @@ -0,0 +1,62 @@ +/* + * FreeRTOS memory safety proofs with CBMC. + * Copyright (C) 2019 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 "FreeRTOS.h" +#include "queue.h" +#include "queue_datastructure.h" +#include "cbmc.h" + +void harness(){ + UBaseType_t uxQueueLength; + UBaseType_t uxItemSize; + + size_t uxQueueStorageSize; + uint8_t *pucQueueStorage = (uint8_t *) pvPortMalloc(uxQueueStorageSize); + + StaticQueue_t *pxStaticQueue = + (StaticQueue_t *) pvPortMalloc(sizeof(StaticQueue_t)); + + uint8_t ucQueueType; + + __CPROVER_assume(uxQueueStorageSize < (UINT32_MAX>>8)); + + // QueueGenericReset does not check for multiplication overflow + __CPROVER_assume(uxItemSize < uxQueueStorageSize/uxQueueLength); + + // QueueGenericCreateStatic asserts positive queue length + __CPROVER_assume(uxQueueLength > ( UBaseType_t ) 0); + + // QueueGenericCreateStatic asserts the following equivalence + __CPROVER_assume( ( pucQueueStorage && uxItemSize ) || + ( !pucQueueStorage && !uxItemSize ) ); + + // QueueGenericCreateStatic asserts nonnull pointer + __CPROVER_assume(pxStaticQueue); + + xQueueGenericCreateStatic( uxQueueLength, uxItemSize, pucQueueStorage, pxStaticQueue, ucQueueType ); +} diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/QueueGenericCreateStatic/README.md b/FreeRTOS/Test/CBMC/proofs/Queue/QueueGenericCreateStatic/README.md new file mode 100644 index 000000000..fb1466647 --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Queue/QueueGenericCreateStatic/README.md @@ -0,0 +1,16 @@ +The harness proves memory safety of +QueueGenericCreateStatic under the assumption made in the harness. + +The principal assumption is that (uxItemSize * uxQueueLength) + sizeof(Queue_t) +does not overflow. Further, ucQueueStorage must only be null iff uxItemSize is null. +In addition, the passed queue storage is assumed to be allocated to the right size. + +The configurations for configSUPPORT_DYNAMIC_ALLOCATION set to 0 and 1 are checked. + +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 diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/QueueGenericReset/Makefile.json b/FreeRTOS/Test/CBMC/proofs/Queue/QueueGenericReset/Makefile.json new file mode 100644 index 000000000..1759310d8 --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Queue/QueueGenericReset/Makefile.json @@ -0,0 +1,53 @@ +# +# FreeRTOS memory safety proofs with CBMC. +# Copyright (C) 2019 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": "QueueGenericReset", + "CBMCFLAGS": [ + "--unwind 1", + "--signed-overflow-check", + "--pointer-overflow-check", + "--unsigned-overflow-check" + ], + "OBJS": [ + "$(ENTRY)_harness.goto", + "$(FREERTOS)/Source/queue.goto", + "$(FREERTOS)/Source/list.goto" + ], + "DEF": [ + "configUSE_TRACE_FACILITY=0", + "configGENERATE_RUN_TIME_STATS=0" + ], + "INC": [ + "." + ], + "GENERATE_HEADER":[ + "queue_datastructure.h" + ] +} + diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/QueueGenericReset/QueueGenericReset_harness.c b/FreeRTOS/Test/CBMC/proofs/Queue/QueueGenericReset/QueueGenericReset_harness.c new file mode 100644 index 000000000..fbe4883a0 --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Queue/QueueGenericReset/QueueGenericReset_harness.c @@ -0,0 +1,45 @@ +/* + * FreeRTOS memory safety proofs with CBMC. + * Copyright (C) 2019 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 "FreeRTOS.h" +#include "queue.h" +#include "queue_init.h" + +#include "cbmc.h" + +struct QueueDefinition; + +void harness() { + BaseType_t xNewQueue; + + QueueHandle_t xQueue = xUnconstrainedQueue(); + if(xQueue != NULL) + { + xQueueGenericReset(xQueue, xNewQueue); + } +} diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/QueueGenericReset/README.md b/FreeRTOS/Test/CBMC/proofs/Queue/QueueGenericReset/README.md new file mode 100644 index 000000000..7645344aa --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Queue/QueueGenericReset/README.md @@ -0,0 +1,12 @@ +Assuming that the QueueHandel_t is not null and the assumptions made +for QueueGenericCreate hold, this harness proves the memory safety of QueueGenericReset. + +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 +* xTaskRemoveFromEventList diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/QueueGenericSend/Configurations.json b/FreeRTOS/Test/CBMC/proofs/Queue/QueueGenericSend/Configurations.json new file mode 100644 index 000000000..64e3e6789 --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Queue/QueueGenericSend/Configurations.json @@ -0,0 +1,76 @@ +# +# FreeRTOS memory safety proofs with CBMC. +# Copyright (C) 2019 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": "QueueGenericSend", + "LOCK_BOUND": 2, + "QUEUE_SEND_BOUND":3, + "CBMCFLAGS": [ + "--unwind 1", + "--signed-overflow-check", + "--pointer-overflow-check", + "--unsigned-overflow-check", + "--unwindset xQueueGenericSend.0:{QUEUE_SEND_BOUND},prvUnlockQueue.0:{LOCK_BOUND},prvUnlockQueue.1:{LOCK_BOUND}", + "--nondet-static" + ], + "OBJS": [ + "$(ENTRY)_harness.goto", + "$(FREERTOS)/Source/queue.goto", + "$(FREERTOS)/Source/list.goto", + "$(FREERTOS)/Test/CBMC/proofs/CBMCStubLibrary/tasksStubs.goto" + ], + "DEF": [ + { + "QueueGenericSend_noQueueSets": [ + "configUSE_TRACE_FACILITY=0", + "configGENERATE_RUN_TIME_STATS=0", + "'mtCOVERAGE_TEST_MARKER()=__CPROVER_assert(1, \"Coverage marker\")'", + "configUSE_QUEUE_SETS=0", + "LOCK_BOUND={LOCK_BOUND}", + "QUEUE_SEND_BOUND={QUEUE_SEND_BOUND}" + ] + }, + { + "QueueGenericSend_QueueSets": [ + "configUSE_TRACE_FACILITY=0", + "configGENERATE_RUN_TIME_STATS=0", + "'mtCOVERAGE_TEST_MARKER()=__CPROVER_assert(1, \"Coverage marker\")'", + "configUSE_QUEUE_SETS=1", + "LOCK_BOUND={LOCK_BOUND}", + "QUEUE_SEND_BOUND={QUEUE_SEND_BOUND}" + ] + } + ], + "INC": [ + "." + ], + "GENERATE_HEADER":[ + "queue_datastructure.h" + ] +} + diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/QueueGenericSend/QueueGenericSend_harness.c b/FreeRTOS/Test/CBMC/proofs/Queue/QueueGenericSend/QueueGenericSend_harness.c new file mode 100644 index 000000000..fae965ad8 --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Queue/QueueGenericSend/QueueGenericSend_harness.c @@ -0,0 +1,127 @@ +/* + * FreeRTOS memory safety proofs with CBMC. + * Copyright (C) 2019 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 "FreeRTOS.h" +#include "queue.h" +#include "queue_init.h" +#include "tasksStubs.h" + +#include "cbmc.h" + +#ifndef LOCK_BOUND + #define LOCK_BOUND 4 +#endif + +#ifndef QUEUE_SEND_BOUND + #define QUEUE_SEND_BOUND 4 +#endif + +#if( configUSE_QUEUE_SETS == 0 ) +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(); + } +} +#else + BaseType_t prvNotifyQueueSetContainer( const Queue_t * const pxQueue ) + { + Queue_t *pxQueueSetContainer = pxQueue->pxQueueSetContainer; + configASSERT( pxQueueSetContainer ); + } + + void prvUnlockQueue( Queue_t * const pxQueue ) { + configASSERT( pxQueue ); + if( pxQueue->pxQueueSetContainer != NULL ) + { + prvNotifyQueueSetContainer(pxQueue); + } + listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ); + pxQueue->cTxLock = queueUNLOCKED; + + listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ); + pxQueue->cRxLock = queueUNLOCKED; + } + +#endif + +void harness(){ + //Initialise the tasksStubs + vInitTaskCheckForTimeOut(0, QUEUE_SEND_BOUND - 1); + xState = nondet_basetype(); + QueueHandle_t xQueue = + xUnconstrainedQueueBoundedItemSize(2); + + TickType_t xTicksToWait; + if(xState == taskSCHEDULER_SUSPENDED){ + xTicksToWait = 0; + } + + if(xQueue){ + void *pvItemToQueue = pvPortMalloc(xQueue->uxItemSize); + BaseType_t xCopyPosition; + + if(xCopyPosition == queueOVERWRITE){ + xQueue->uxLength = 1; + } + + if(xQueue->uxItemSize == 0) + { + /* uxQueue->xQueueType is a pointer to the head of the queue storage area. + If an item has a sice, this pointer must not be modified after init. + Otherwise some of the write statements will fail. */ + xQueue->uxQueueType = nondet_int8_t(); + pvItemToQueue = 0; + } + /* This code checks explicitly for violations of the pxQueue->uxMessagesWaiting < pxQueue->uxLength + invariant. */ + xQueue->uxMessagesWaiting = nondet_UBaseType_t(); + + /* These values are decremented during a while loop interacting with task.c. + This interaction is currently abstracted away.*/ + xQueue->cTxLock = LOCK_BOUND - 1; + xQueue->cRxLock = LOCK_BOUND - 1; + + if(!pvItemToQueue){ + xQueue->uxItemSize = 0; + } + + xQueueGenericSend( xQueue, pvItemToQueue, xTicksToWait, xCopyPosition ); + } +} + diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/QueueGenericSend/README.md b/FreeRTOS/Test/CBMC/proofs/Queue/QueueGenericSend/README.md new file mode 100644 index 000000000..9dae1be0a --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Queue/QueueGenericSend/README.md @@ -0,0 +1,19 @@ +The harness in this folder proves the memory safety of QueueGenericSend +with and without QueueSets. It is abstracting away the task pool and concurrency +related functions and assumes the parameters to be initialized to valid data structures. +Further, prvCopyDataToQueue, prvUnlockQueue and prvNotifyQueueSetContainer are abstracted away. + +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 +* vTaskInternalSetTimeOutState +* vTaskMissedYield +* vTaskPlaceOnEventList +* vTaskSuspendAll +* xTaskRemoveFromEventList +* xTaskResumeAll diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/QueueGenericSendFromISR/Configurations.json b/FreeRTOS/Test/CBMC/proofs/Queue/QueueGenericSendFromISR/Configurations.json new file mode 100644 index 000000000..92892ca85 --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Queue/QueueGenericSendFromISR/Configurations.json @@ -0,0 +1,68 @@ +# +# FreeRTOS memory safety proofs with CBMC. +# Copyright (C) 2019 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": "QueueGenericSendFromISR", + "CBMCFLAGS": [ + "--unwind 1", + "--signed-overflow-check", + "--pointer-overflow-check", + "--unsigned-overflow-check", + "--nondet-static" + ], + "OBJS": [ + "$(ENTRY)_harness.goto", + "$(FREERTOS)/Source/queue.goto", + "$(FREERTOS)/Source/list.goto" + ], + "DEF": [ + { + "QueueGenericSendFromISR_noQueueSets": [ + "configUSE_TRACE_FACILITY=0", + "configGENERATE_RUN_TIME_STATS=0", + "'mtCOVERAGE_TEST_MARKER()=__CPROVER_assert(1, \"Coverage marker\")'", + "configUSE_QUEUE_SETS=0" + ] + }, + { + "QueueGenericSendFromISR_QueueSets": [ + "configUSE_TRACE_FACILITY=0", + "configGENERATE_RUN_TIME_STATS=0", + "'mtCOVERAGE_TEST_MARKER()=__CPROVER_assert(1, \"Coverage marker\")'", + "configUSE_QUEUE_SETS=1" + ] + } + ], + "INC": [ + "." + ], + "GENERATE_HEADER":[ + "queue_datastructure.h" + ] +} + diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/QueueGenericSendFromISR/QueueGenericSendFromISR_harness.c b/FreeRTOS/Test/CBMC/proofs/Queue/QueueGenericSendFromISR/QueueGenericSendFromISR_harness.c new file mode 100644 index 000000000..0c8a98cf2 --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Queue/QueueGenericSendFromISR/QueueGenericSendFromISR_harness.c @@ -0,0 +1,85 @@ +/* + * FreeRTOS memory safety proofs with CBMC. + * Copyright (C) 2019 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 "FreeRTOS.h" +#include "queue.h" +#include "queue_init.h" + +#include "cbmc.h" + +#ifndef ITEM_BOUND + #define ITEM_BOUND 10 +#endif + +#if( configUSE_QUEUE_SETS == 0 ) + 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 + +void harness(){ + QueueHandle_t xQueue = xUnconstrainedQueueBoundedItemSize(ITEM_BOUND); + + + if( xQueue ){ + void *pvItemToQueue = pvPortMalloc(xQueue->uxItemSize); + BaseType_t *xHigherPriorityTaskWoken = pvPortMalloc(sizeof(BaseType_t)); + BaseType_t xCopyPosition; + if(xQueue->uxItemSize == 0) + { + /* uxQueue->xQueueType is a pointer to the head of the queue storage area. + If an item has a size, this pointer must not be modified after init. + Otherwise some of the write statements will fail. */ + xQueue->uxQueueType = nondet_int8_t(); + pvItemToQueue = 0; + } + /* This code checks explicitly for violations of the pxQueue->uxMessagesWaiting < pxQueue->uxLength + invariant. */ + xQueue->uxMessagesWaiting = nondet_UBaseType_t(); + if(!pvItemToQueue){ + xQueue->uxItemSize = 0; + } + if(xCopyPosition == 2 ){ + __CPROVER_assume(xQueue->uxLength == 1); + } + xQueueGenericSendFromISR( xQueue, pvItemToQueue, xHigherPriorityTaskWoken, xCopyPosition ); + } +} diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/QueueGenericSendFromISR/README.md b/FreeRTOS/Test/CBMC/proofs/Queue/QueueGenericSendFromISR/README.md new file mode 100644 index 000000000..cfc20618b --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Queue/QueueGenericSendFromISR/README.md @@ -0,0 +1,12 @@ +The harness in this folder proves the memory safety of QueueGenericSendFromISR +with and without QueueSets. It is abstracting away the task pool and concurrency +related functions. Further, it uses a stub for prvCopyDataToQueue. + +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 +* xTaskRemoveFromEventList diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/QueueGetMutexHolder/Makefile.json b/FreeRTOS/Test/CBMC/proofs/Queue/QueueGetMutexHolder/Makefile.json new file mode 100644 index 000000000..ecc2b6230 --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Queue/QueueGetMutexHolder/Makefile.json @@ -0,0 +1,53 @@ +# +# FreeRTOS memory safety proofs with CBMC. +# Copyright (C) 2019 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": "QueueGetMutexHolder", + "CBMCFLAGS": [ + "--unwind 1", + "--signed-overflow-check", + "--pointer-overflow-check", + "--unsigned-overflow-check" + ], + "OBJS": [ + "$(ENTRY)_harness.goto", + "$(FREERTOS)/Source/queue.goto", + "$(FREERTOS)/Source/list.goto" + ], + "DEF": [ + "configUSE_TRACE_FACILITY=0", + "configGENERATE_RUN_TIME_STATS=0" + ], + "INC": [ + "." + ], + "GENERATE_HEADER": [ + "queue_datastructure.h" + ] +} + diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/QueueGetMutexHolder/QueueGetMutexHolder_harness.c b/FreeRTOS/Test/CBMC/proofs/Queue/QueueGetMutexHolder/QueueGetMutexHolder_harness.c new file mode 100644 index 000000000..1bba9b7f8 --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Queue/QueueGetMutexHolder/QueueGetMutexHolder_harness.c @@ -0,0 +1,41 @@ +/* + * FreeRTOS memory safety proofs with CBMC. + * Copyright (C) 2019 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 "FreeRTOS.h" +#include "queue_init.h" +#include "queue.h" + +#include "cbmc.h" + +void harness() { + QueueHandle_t xSemaphore = xUnconstrainedQueue(); + if (xSemaphore) { + xSemaphore->uxQueueType = nondet_uint8_t(); + xQueueGetMutexHolder(xSemaphore); + } +} diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/QueueGetMutexHolder/README.md b/FreeRTOS/Test/CBMC/proofs/Queue/QueueGetMutexHolder/README.md new file mode 100644 index 000000000..d028ea9e7 --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Queue/QueueGetMutexHolder/README.md @@ -0,0 +1,10 @@ +This harness proves the memory safety of QueueGetMutexHolder assuming the passed +semaphore is not null. + +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 diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/QueueGetMutexHolderFromISR/Makefile.json b/FreeRTOS/Test/CBMC/proofs/Queue/QueueGetMutexHolderFromISR/Makefile.json new file mode 100644 index 000000000..647a0d03f --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Queue/QueueGetMutexHolderFromISR/Makefile.json @@ -0,0 +1,53 @@ +# +# FreeRTOS memory safety proofs with CBMC. +# Copyright (C) 2019 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": "QueueGetMutexHolderFromISR", + "CBMCFLAGS": [ + "--unwind 1", + "--signed-overflow-check", + "--pointer-overflow-check", + "--unsigned-overflow-check" + ], + "OBJS": [ + "$(ENTRY)_harness.goto", + "$(FREERTOS)/Source/queue.goto", + "$(FREERTOS)/Source/list.goto" + ], + "DEF": [ + "configUSE_TRACE_FACILITY=0", + "configGENERATE_RUN_TIME_STATS=0" + ], + "INC": [ + "." + ], + "GENERATE_HEADER": [ + "queue_datastructure.h" + ] +} + diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/QueueGetMutexHolderFromISR/QueueGetMutexHolderFromISR_harness.c b/FreeRTOS/Test/CBMC/proofs/Queue/QueueGetMutexHolderFromISR/QueueGetMutexHolderFromISR_harness.c new file mode 100644 index 000000000..a0543a70c --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Queue/QueueGetMutexHolderFromISR/QueueGetMutexHolderFromISR_harness.c @@ -0,0 +1,41 @@ +/* + * FreeRTOS memory safety proofs with CBMC. + * Copyright (C) 2019 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 "FreeRTOS.h" +#include "queue.h" +#include "queue_datastructure.h" + +#include "cbmc.h" + +void harness(){ + QueueHandle_t xSemaphore = pvPortMalloc(sizeof(Queue_t)); + if (xSemaphore) { + xQueueGetMutexHolderFromISR( xSemaphore ); + } +} + diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/QueueGetMutexHolderFromISR/README.md b/FreeRTOS/Test/CBMC/proofs/Queue/QueueGetMutexHolderFromISR/README.md new file mode 100644 index 000000000..629ea7336 --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Queue/QueueGetMutexHolderFromISR/README.md @@ -0,0 +1,5 @@ +Assuming that xSemaphore is a pointer to an allocated Queue_t instance, +this harness proves the memory safety of QueueGetMutexHolderFromISR. + +This proof is a work-in-progress. Proof assumptions are described in +the harness. diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/QueueGiveFromISR/Configurations.json b/FreeRTOS/Test/CBMC/proofs/Queue/QueueGiveFromISR/Configurations.json new file mode 100644 index 000000000..ff71fd642 --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Queue/QueueGiveFromISR/Configurations.json @@ -0,0 +1,72 @@ +# +# FreeRTOS memory safety proofs with CBMC. +# Copyright (C) 2019 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": "QueueGiveFromISR", + "CBMCFLAGS": [ + "--unwind 1", + "--signed-overflow-check", + "--pointer-overflow-check", + "--unsigned-overflow-check", + "--nondet-static" + ], + "OBJS": [ + "$(ENTRY)_harness.goto", + "$(FREERTOS)/Source/queue.goto", + "$(FREERTOS)/Source/list.goto" + ], + "DEF": [ + { + "QueueGiveFromISR_default": [ + "configUSE_TRACE_FACILITY=0", + "configGENERATE_RUN_TIME_STATS=0", + "'mtCOVERAGE_TEST_MARKER()=__CPROVER_assert(1, \"Coverage marker\")'", + "configSUPPORT_STATIC_ALLOCATION=1", + "configSUPPORT_DYNAMIC_ALLOCATION=1", + "configUSE_QUEUE_SETS=0" + ] + }, + { + "QueueGiveFromISR_QueueSets": [ + "configUSE_TRACE_FACILITY=0", + "configGENERATE_RUN_TIME_STATS=0", + "'mtCOVERAGE_TEST_MARKER()=__CPROVER_assert(1, \"Coverage marker\")'", + "configSUPPORT_STATIC_ALLOCATION=1", + "configSUPPORT_DYNAMIC_ALLOCATION=1", + "configUSE_QUEUE_SETS=1" + ] + } + ], + "INC": [ + "$(FREERTOS)/Test/CBMC/proofs/CBMCStubLibrary/", + "." + ], + "GENERATE_HEADER": [ + "queue_datastructure.h" + ] +} diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/QueueGiveFromISR/QueueGiveFromISR_harness.c b/FreeRTOS/Test/CBMC/proofs/Queue/QueueGiveFromISR/QueueGiveFromISR_harness.c new file mode 100644 index 000000000..b6be1aa80 --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Queue/QueueGiveFromISR/QueueGiveFromISR_harness.c @@ -0,0 +1,43 @@ +/* + * FreeRTOS memory safety proofs with CBMC. + * Copyright (C) 2019 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 "FreeRTOS.h" +#include "queue.h" +#include "queue_init.h" + +#include "cbmc.h" + +void harness(){ + QueueHandle_t xQueue = xUnconstrainedMutex(); + BaseType_t *xHigherPriorityTaskWoken = pvPortMalloc(sizeof(BaseType_t)); + if(xQueue){ + xQueue->uxMessagesWaiting = nondet_UBaseType_t(); + xQueueGiveFromISR( xQueue, xHigherPriorityTaskWoken ); + } + +} diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/QueueGiveFromISR/README.md b/FreeRTOS/Test/CBMC/proofs/Queue/QueueGiveFromISR/README.md new file mode 100644 index 000000000..75da9156d --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Queue/QueueGiveFromISR/README.md @@ -0,0 +1,15 @@ +Assuming the xQueue is allocated to a valid memory block and abstracting +away concurrency and task pool related functions, this harness proves the memory +safety of QueueGiveFromISR. + +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 +* xTaskGetSchedulerState +* xTaskPriorityDisinherit +* xTaskRemoveFromEventList diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/QueueGiveMutexRecursive/Makefile.json b/FreeRTOS/Test/CBMC/proofs/Queue/QueueGiveMutexRecursive/Makefile.json new file mode 100644 index 000000000..8d1720fcd --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Queue/QueueGiveMutexRecursive/Makefile.json @@ -0,0 +1,54 @@ +# +# FreeRTOS memory safety proofs with CBMC. +# Copyright (C) 2019 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": "QueueGiveMutexRecursive", + "CBMCFLAGS": [ + "--unwind 1", + "--signed-overflow-check", + "--pointer-overflow-check", + "--unsigned-overflow-check" + ], + "OBJS": [ + "$(ENTRY)_harness.goto", + "$(FREERTOS)/Source/queue.goto", + "$(FREERTOS)/Source/list.goto" + ], + "DEF": [ + "configUSE_TRACE_FACILITY=0", + "configGENERATE_RUN_TIME_STATS=0", + "configUSE_RECURSIVE_MUTEXES=1" + ], + "INC": [ + "." + ], + "GENERATE_HEADER": [ + "queue_datastructure.h" + ] +} + diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/QueueGiveMutexRecursive/QueueGiveMutexRecursive_harness.c b/FreeRTOS/Test/CBMC/proofs/Queue/QueueGiveMutexRecursive/QueueGiveMutexRecursive_harness.c new file mode 100644 index 000000000..6df3a36ee --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Queue/QueueGiveMutexRecursive/QueueGiveMutexRecursive_harness.c @@ -0,0 +1,48 @@ +/* + * FreeRTOS memory safety proofs with CBMC. + * Copyright (C) 2019 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 "FreeRTOS.h" +#include "queue.h" +#include "queue_datastructure.h" + +#include "cbmc.h" + +void harness() { + uint8_t ucQueueType; + QueueHandle_t xMutex = + xQueueCreateMutex( ucQueueType); + if (xMutex) { + xMutex->uxQueueType = ucQueueType; + UBaseType_t uxCounter; + /* This assumption is explained in the queue.c file inside the method body + xQueueGiveMutexRecursive and guards against an underflow error. */ + __CPROVER_assume(uxCounter > 0); + xMutex->u.xSemaphore.uxRecursiveCallCount = uxCounter; + xQueueGiveMutexRecursive(xMutex); + } +} diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/QueueGiveMutexRecursive/README.md b/FreeRTOS/Test/CBMC/proofs/Queue/QueueGiveMutexRecursive/README.md new file mode 100644 index 000000000..962350e52 --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Queue/QueueGiveMutexRecursive/README.md @@ -0,0 +1,16 @@ +Assuming that the xMutex parameter is initialized to a valid pointer and +abstracting concurrency and task pool related functions, this harness +proves the memory safety of QueueGiveMutexRecursive. + +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 +* xTaskGetCurrentTaskHandle +* xTaskGetSchedulerState +* xTaskPriorityDisinherit +* xTaskRemoveFromEventList diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/QueueMessagesWaiting/Makefile.json b/FreeRTOS/Test/CBMC/proofs/Queue/QueueMessagesWaiting/Makefile.json new file mode 100644 index 000000000..6c8806b2c --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Queue/QueueMessagesWaiting/Makefile.json @@ -0,0 +1,52 @@ +# +# FreeRTOS memory safety proofs with CBMC. +# Copyright (C) 2019 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": "QueueMessagesWaiting", + "CBMCFLAGS": [ + "--unwind 1", + "--signed-overflow-check", + "--pointer-overflow-check", + "--unsigned-overflow-check" + ], + "OBJS": [ + "$(ENTRY)_harness.goto", + "$(FREERTOS)/Source/queue.goto", + "$(FREERTOS)/Source/list.goto" + ], + "DEF": [ + "configUSE_TRACE_FACILITY=0", + "configGENERATE_RUN_TIME_STATS=0" + ], + "INC": [ + "." + ], + "GENERATE_HEADER": [ + "queue_datastructure.h" + ] +} diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/QueueMessagesWaiting/QueueMessagesWaiting_harness.c b/FreeRTOS/Test/CBMC/proofs/Queue/QueueMessagesWaiting/QueueMessagesWaiting_harness.c new file mode 100644 index 000000000..8e5f3d050 --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Queue/QueueMessagesWaiting/QueueMessagesWaiting_harness.c @@ -0,0 +1,41 @@ +/* + * FreeRTOS memory safety proofs with CBMC. + * Copyright (C) 2019 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 "FreeRTOS.h" +#include "queue.h" +#include "queue_datastructure.h" + +#include "cbmc.h" + +void harness(){ + QueueHandle_t xQueue = pvPortMalloc(sizeof(Queue_t)); + + if(xQueue){ + uxQueueMessagesWaiting( xQueue ); + } +} diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/QueueMessagesWaiting/README.md b/FreeRTOS/Test/CBMC/proofs/Queue/QueueMessagesWaiting/README.md new file mode 100644 index 000000000..811b5abb5 --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Queue/QueueMessagesWaiting/README.md @@ -0,0 +1,12 @@ +Assuming the parameter passed to QueueMessagesWaiting is a pointer to a Queue_t +struct, this harness proves the memory safety of QueueMessagesWaiting. +The concurrency related functions vPortEnterCrititcal and vPortExitCritical +are abstracted away. + +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 diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/QueuePeek/Makefile.json b/FreeRTOS/Test/CBMC/proofs/Queue/QueuePeek/Makefile.json new file mode 100644 index 000000000..797d788a1 --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Queue/QueuePeek/Makefile.json @@ -0,0 +1,60 @@ +# +# FreeRTOS memory safety proofs with CBMC. +# Copyright (C) 2019 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": "QueuePeek", + "LOCK_BOUND":4, + "QUEUE_PEEK_BOUND" :4, + "CBMCFLAGS": [ + "--unwind 1", + "--signed-overflow-check", + "--pointer-overflow-check", + "--unsigned-overflow-check", + "--unwindset prvUnlockQueue.0:{LOCK_BOUND},prvUnlockQueue.1:{LOCK_BOUND},xQueuePeek.0:{QUEUE_PEEK_BOUND}", + "--nondet-static" + ], + "OBJS": [ + "$(ENTRY)_harness.goto", + "$(FREERTOS)/Source/queue.goto", + "$(FREERTOS)/Source/list.goto", + "$(FREERTOS)/Test/CBMC/proofs/CBMCStubLibrary/tasksStubs.goto" + ], + "DEF": [ + "configUSE_TRACE_FACILITY=0", + "configGENERATE_RUN_TIME_STATS=0", + "LOCK_BOUND={LOCK_BOUND}", + "QUEUE_PEEK_BOUND={QUEUE_PEEK_BOUND}", + "INCLUDE_xTaskGetSchedulerState=1" + ], + "INC": [ + "." + ], + "GENERATE_HEADER": [ + "queue_datastructure.h" + ] +} diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/QueuePeek/QueuePeek_harness.c b/FreeRTOS/Test/CBMC/proofs/Queue/QueuePeek/QueuePeek_harness.c new file mode 100644 index 000000000..53c2c9050 --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Queue/QueuePeek/QueuePeek_harness.c @@ -0,0 +1,79 @@ +/* + * FreeRTOS memory safety proofs with CBMC. + * Copyright (C) 2019 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 "FreeRTOS.h" +#include "queue.h" +#include "queue_init.h" +#include "tasksStubs.h" + +#include "cbmc.h" + +#ifndef LOCK_BOUND + #define LOCK_BOUND 4 +#endif + +#ifndef QUEUE_PEEK_BOUND + #define QUEUE_PEEK_BOUND 4 +#endif + +QueueHandle_t xQueue; + + +/* This method is called to initialize pxTimeOut. + Setting up the data structure is not interesting for the proof, + but the harness uses it to model a release + on the queue after first check. */ +void vTaskInternalSetTimeOutState( TimeOut_t * const pxTimeOut ){ + xQueue-> uxMessagesWaiting = nondet_BaseType_t(); +} + +void harness(){ + xQueue = xUnconstrainedQueueBoundedItemSize(10); + + //Initialise the tasksStubs + vInitTaskCheckForTimeOut(0, QUEUE_PEEK_BOUND - 1); + + TickType_t xTicksToWait; + if(xState == taskSCHEDULER_SUSPENDED){ + xTicksToWait = 0; + } + + if(xQueue){ + __CPROVER_assume(xQueue->cTxLock < LOCK_BOUND - 1); + __CPROVER_assume(xQueue->cRxLock < LOCK_BOUND - 1); + + void *pvItemToQueue = pvPortMalloc(xQueue->uxItemSize); + + /* In case malloc fails as this is otherwise an invariant violation. */ + if(!pvItemToQueue){ + xQueue->uxItemSize = 0; + } + + xQueuePeek( xQueue, pvItemToQueue, xTicksToWait ); + } +} diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/QueuePeek/README.md b/FreeRTOS/Test/CBMC/proofs/Queue/QueuePeek/README.md new file mode 100644 index 000000000..87a791e7c --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Queue/QueuePeek/README.md @@ -0,0 +1,18 @@ +Assuming xQueue and pvItemToQueue are non-null pointers allocated to the right +size, this harness proves the memory safety of QueueGenericPeek. Some of the +task pool behavior is abstracted away. Nevertheless, some of the concurrent +behavior has been modeled to allow full coverage of QueuePeek. + +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 +* vTaskMissedYield +* vTaskPlaceOnEventList +* vTaskSuspendAll +* xTaskRemoveFromEventList +* xTaskResumeAll diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/QueueReceive/Makefile.json b/FreeRTOS/Test/CBMC/proofs/Queue/QueueReceive/Makefile.json new file mode 100644 index 000000000..568e517b1 --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Queue/QueueReceive/Makefile.json @@ -0,0 +1,61 @@ +# +# FreeRTOS memory safety proofs with CBMC. +# Copyright (C) 2019 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": "QueueReceive", + "LOCK_BOUND": 2, + "QUEUE_RECEIVE_BOUND": 3, + "CBMCFLAGS": [ + "--unwind 1", + "--signed-overflow-check", + "--pointer-overflow-check", + "--unsigned-overflow-check", + "--unwindset xQueueReceive.0:{QUEUE_RECEIVE_BOUND},prvUnlockQueue.0:{LOCK_BOUND},prvUnlockQueue.1:{LOCK_BOUND}", + "--nondet-static" + ], + "OBJS": [ + "$(ENTRY)_harness.goto", + "$(FREERTOS)/Source/queue.goto", + "$(FREERTOS)/Source/list.goto", + "$(FREERTOS)/Test/CBMC/proofs/CBMCStubLibrary/tasksStubs.goto" + ], + "DEF": [ + "configUSE_TRACE_FACILITY=0", + "configGENERATE_RUN_TIME_STATS=0", + "INCLUDE_xTaskGetSchedulerState=1", + "QUEUE_RECEIVE_BOUND={QUEUE_RECEIVE_BOUND}", + "LOCK_BOUND={LOCK_BOUND}" + ], + "INC": [ + "." + ], + "GENERATE_HEADER": [ + "queue_datastructure.h" + ] +} + diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/QueueReceive/QueueReceive_harness.c b/FreeRTOS/Test/CBMC/proofs/Queue/QueueReceive/QueueReceive_harness.c new file mode 100644 index 000000000..533f69caf --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Queue/QueueReceive/QueueReceive_harness.c @@ -0,0 +1,88 @@ +/* + * FreeRTOS memory safety proofs with CBMC. + * Copyright (C) 2019 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 "FreeRTOS.h" +#include "queue.h" +#include "queue_init.h" +#include "tasksStubs.h" +#include "cbmc.h" + +/* prvUnlockQueue is going to decrement this value to 0 in the loop. + We need a bound for the loop. Using 4 has a reasonable performance resulting + in 3 unwinding iterations of the loop. The loop is mostly modifying a + data structure in task.c that is not in the scope of the proof. */ +#ifndef LOCK_BOUND + #define LOCK_BOUND 4 +#endif + +/* This code checks for time outs. This value is used to bound the time out + wait period. The stub function xTaskCheckForTimeOut used to model + this wait time will be bounded to this define. */ +#ifndef QUEUE_RECEIVE_BOUND + #define QUEUE_RECEIVE_BOUND 4 +#endif + +/* If the item size is not bounded, the proof does not finish in a reasonable + time due to the involved memcpy commands. */ +#ifndef MAX_ITEM_SIZE + #define MAX_ITEM_SIZE 20 +#endif + +QueueHandle_t xQueue; + +/* This method is used to model side effects of concurrency. + The initialization of pxTimeOut is not relevant for this harness. */ +void vTaskInternalSetTimeOutState( TimeOut_t * const pxTimeOut ){ + __CPROVER_assert(__CPROVER_w_ok(&(pxTimeOut->xOverflowCount), sizeof(BaseType_t)), "pxTimeOut should be a valid pointer and xOverflowCount writable"); + __CPROVER_assert(__CPROVER_w_ok(&(pxTimeOut->xTimeOnEntering), sizeof(TickType_t)), "pxTimeOut should be a valid pointer and xTimeOnEntering writable"); + xQueue->uxMessagesWaiting = nondet_BaseType_t(); +} + +void harness(){ + vInitTaskCheckForTimeOut(0, QUEUE_RECEIVE_BOUND - 1); + + xQueue = xUnconstrainedQueueBoundedItemSize(MAX_ITEM_SIZE); + + + TickType_t xTicksToWait; + if(xState == taskSCHEDULER_SUSPENDED){ + xTicksToWait = 0; + } + + if(xQueue){ + xQueue->cTxLock = LOCK_BOUND - 1; + xQueue->cRxLock = LOCK_BOUND - 1; + + void *pvBuffer = pvPortMalloc(xQueue->uxItemSize); + if(!pvBuffer){ + xQueue->uxItemSize = 0; + } + xQueueReceive( xQueue, pvBuffer, xTicksToWait ); + } + +} diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/QueueReceive/README.md b/FreeRTOS/Test/CBMC/proofs/Queue/QueueReceive/README.md new file mode 100644 index 000000000..b76b9c5e0 --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Queue/QueueReceive/README.md @@ -0,0 +1,17 @@ +Assuming the bound described in the harness, this harness proves memory safety +for the QueueReceive function abstracting away +the task pool and concurrency functions. + +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 +* vTaskMissedYield +* vTaskPlaceOnEventList +* vTaskSuspendAll +* xTaskRemoveFromEventList +* xTaskResumeAll diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/QueueReceiveFromISR/Makefile.json b/FreeRTOS/Test/CBMC/proofs/Queue/QueueReceiveFromISR/Makefile.json new file mode 100644 index 000000000..e084d22f2 --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Queue/QueueReceiveFromISR/Makefile.json @@ -0,0 +1,54 @@ +# +# FreeRTOS memory safety proofs with CBMC. +# Copyright (C) 2019 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": "QueueReceiveFromISR", + "CBMCFLAGS": [ + "--unwind 1", + "--signed-overflow-check", + "--pointer-overflow-check", + "--unsigned-overflow-check" + ], + "OBJS": [ + "$(ENTRY)_harness.goto", + "$(FREERTOS)/Source/queue.goto", + "$(FREERTOS)/Source/list.goto", + "$(FREERTOS)/Test/CBMC/proofs/CBMCStubLibrary/tasksStubs.goto" + ], + "DEF": [ + "configUSE_TRACE_FACILITY=0", + "configGENERATE_RUN_TIME_STATS=0", + "'mtCOVERAGE_TEST_MARKER()=__CPROVER_assert(1, \"Coverage marker\")'" + ], + "INC": [ + "." + ], + "GENERATE_HEADER": [ + "queue_datastructure.h" + ] +} diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/QueueReceiveFromISR/QueueReceiveFromISR_harness.c b/FreeRTOS/Test/CBMC/proofs/Queue/QueueReceiveFromISR/QueueReceiveFromISR_harness.c new file mode 100644 index 000000000..9a4b2cf2a --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Queue/QueueReceiveFromISR/QueueReceiveFromISR_harness.c @@ -0,0 +1,53 @@ +/* + * FreeRTOS memory safety proofs with CBMC. + * Copyright (C) 2019 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 "FreeRTOS.h" +#include "queue.h" +#include "queue_init.h" +#include "cbmc.h" + +/* If the item size is not bounded, the proof does not finish in a reasonable + time due to the involved memcpy commands. */ +#ifndef MAX_ITEM_SIZE + #define MAX_ITEM_SIZE 10 +#endif + +void harness(){ + QueueHandle_t xQueue = + xUnconstrainedQueueBoundedItemSize(MAX_ITEM_SIZE); + + BaseType_t *xHigherPriorityTaskWoken = pvPortMalloc(sizeof(BaseType_t)); + + if(xQueue){ + void *pvBuffer = pvPortMalloc(xQueue->uxItemSize); + if(!pvBuffer){ + xQueue->uxItemSize = 0; + } + xQueueReceiveFromISR( xQueue, pvBuffer, xHigherPriorityTaskWoken ); + } +} diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/QueueReceiveFromISR/README.md b/FreeRTOS/Test/CBMC/proofs/Queue/QueueReceiveFromISR/README.md new file mode 100644 index 000000000..7da35e498 --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Queue/QueueReceiveFromISR/README.md @@ -0,0 +1,12 @@ +Assuming the bound declared in the harness, this harness proves the memory +safety the QueueReceiveFromISR abstracting +away the task pool and concurrency related functions. + +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 +* xTaskRemoveFromEventList diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/QueueSemaphoreTake/Makefile.json b/FreeRTOS/Test/CBMC/proofs/Queue/QueueSemaphoreTake/Makefile.json new file mode 100644 index 000000000..07f7c1034 --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Queue/QueueSemaphoreTake/Makefile.json @@ -0,0 +1,60 @@ +# +# FreeRTOS memory safety proofs with CBMC. +# Copyright (C) 2019 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": "QueueSemaphoreTake", + + # This bound on queue size is needed to bound a loop in prvUnlockQueue + "QUEUE_BOUND": 5, + + "CBMCFLAGS": [ + "--unwind 2", + "--signed-overflow-check", + "--pointer-overflow-check", + "--unsigned-overflow-check", + "--nondet-static", + "--unwindset prvUnlockQueue.0:{QUEUE_BOUND},prvUnlockQueue.1:{QUEUE_BOUND},xQueueSemaphoreTake.0:3" + ], + "OBJS": [ + "$(ENTRY)_harness.goto", + "$(FREERTOS)/Source/queue.goto", + "$(FREERTOS)/Source/list.goto", + "$(FREERTOS)/Test/CBMC/proofs/CBMCStubLibrary/tasksStubs.goto" + ], + "DEF": [ + "configUSE_TRACE_FACILITY=0", + "configGENERATE_RUN_TIME_STATS=0", + "PRV_UNLOCK_QUEUE_BOUND={QUEUE_BOUND}" + ], + "INC": [ + "." + ], + "GENERATE_HEADER": [ + "queue_datastructure.h" + ] +} diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/QueueSemaphoreTake/QueueSemaphoreTake_harness.c b/FreeRTOS/Test/CBMC/proofs/Queue/QueueSemaphoreTake/QueueSemaphoreTake_harness.c new file mode 100644 index 000000000..21fdbf80e --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Queue/QueueSemaphoreTake/QueueSemaphoreTake_harness.c @@ -0,0 +1,88 @@ +/* + * FreeRTOS memory safety proofs with CBMC. + * Copyright (C) 2019 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 "FreeRTOS.h" +#include "queue.h" +#include "queue_init.h" +#include "tasksStubs.h" +#include "cbmc.h" + +BaseType_t state; +QueueHandle_t xQueue; +BaseType_t counter; + +BaseType_t xTaskGetSchedulerState(void) +{ + return state; +} + +void vTaskInternalSetTimeOutState( TimeOut_t * const pxTimeOut ) +{ + /* QueueSemaphoreTake might be blocked to wait for + another process to release a token to the semaphore. + This is currently not in the CBMC model. Anyhow, + vTaskInternalSetTimeOutState is set a timeout for + QueueSemaphoreTake operation. We use this to model a successful + release during wait time. */ + UBaseType_t bound; + __CPROVER_assume((bound >= 0 && xQueue->uxLength >= bound)); + xQueue->uxMessagesWaiting = bound; +} + +void harness() +{ + /* Init task stub to make sure that the third loop iteration + simulates a time out */ + vInitTaskCheckForTimeOut(0, 3); + + xQueue = xUnconstrainedMutex(); + TickType_t xTicksToWait; + + if(state == taskSCHEDULER_SUSPENDED){ + xTicksToWait = 0; + } + if (xQueue) { + /* Bounding the loop in prvUnlockQueue to + PRV_UNLOCK_QUEUE_BOUND. As the loop is not relevant + in this proof the value might be set to any + positive 8-bit integer value. We subtract one, + because the bound must be one greater than the + amount of loop iterations. */ + __CPROVER_assert(PRV_UNLOCK_QUEUE_BOUND > 0, "Make sure, a valid macro value is chosen."); + xQueue->cTxLock = PRV_UNLOCK_QUEUE_BOUND - 1; + xQueue->cRxLock = PRV_UNLOCK_QUEUE_BOUND - 1; + ((&(xQueue->xTasksWaitingToReceive))->xListEnd).pxNext->xItemValue = nondet_ticktype(); + + /* This assumptions is required to prevent an overflow in l. 2057 of queue.c + in the prvGetDisinheritPriorityAfterTimeout() function. */ + __CPROVER_assume( ( + ( UBaseType_t ) listGET_ITEM_VALUE_OF_HEAD_ENTRY( &( xQueue->xTasksWaitingToReceive ) ) + <= ( ( UBaseType_t ) configMAX_PRIORITIES))); + xQueueSemaphoreTake(xQueue, xTicksToWait); + } +} diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/QueueSemaphoreTake/README.md b/FreeRTOS/Test/CBMC/proofs/Queue/QueueSemaphoreTake/README.md new file mode 100644 index 000000000..27122656a --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Queue/QueueSemaphoreTake/README.md @@ -0,0 +1,22 @@ +Assuming the bound specified in the harness and abstracting the task pool and +concurrency functions, this harness proves the memory safety of QueueSemaphoreTake. +Some of the task pool functions are used to model concurrent behavior required +to trigger all branches during the model creation. + +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: + +* pvTaskIncrementMutexHeldCount +* vPortEnterCritical +* vPortExitCritical +* vPortGenerateSimulatedInterrupt +* vTaskMissedYield +* vTaskPlaceOnEventList +* vTaskPriorityDisinheritAfterTimeout +* vTaskSuspendAll +* xTaskPriorityDisinherit +* xTaskPriorityInherit +* xTaskRemoveFromEventList +* xTaskResumeAll diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/QueueSpacesAvailable/Makefile.json b/FreeRTOS/Test/CBMC/proofs/Queue/QueueSpacesAvailable/Makefile.json new file mode 100644 index 000000000..33b6e6cf2 --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Queue/QueueSpacesAvailable/Makefile.json @@ -0,0 +1,52 @@ +# +# FreeRTOS memory safety proofs with CBMC. +# Copyright (C) 2019 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": "QueueSpacesAvailable", + "CBMCFLAGS": [ + "--unwind 1", + "--signed-overflow-check", + "--pointer-overflow-check", + "--unsigned-overflow-check" + ], + "OBJS": [ + "$(ENTRY)_harness.goto", + "$(FREERTOS)/Source/queue.goto", + "$(FREERTOS)/Source/list.goto" + ], + "DEF": [ + "configUSE_TRACE_FACILITY=0", + "configGENERATE_RUN_TIME_STATS=0" + ], + "INC": [ + "." + ], + "GENERATE_HEADER": [ + "queue_datastructure.h" + ] +} diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/QueueSpacesAvailable/QueueSpacesAvailable_harness.c b/FreeRTOS/Test/CBMC/proofs/Queue/QueueSpacesAvailable/QueueSpacesAvailable_harness.c new file mode 100644 index 000000000..c56f9008e --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Queue/QueueSpacesAvailable/QueueSpacesAvailable_harness.c @@ -0,0 +1,41 @@ +/* + * FreeRTOS memory safety proofs with CBMC. + * Copyright (C) 2019 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 "FreeRTOS.h" +#include "queue.h" +#include "queue_init.h" +#include "cbmc.h" + +void harness(){ + QueueHandle_t xQueue = xUnconstrainedQueue(); + + // QueueSpacesAvailable asserts nonnull pointer + __CPROVER_assume(xQueue); + + uxQueueSpacesAvailable( xQueue ); +} diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/QueueSpacesAvailable/README.md b/FreeRTOS/Test/CBMC/proofs/Queue/QueueSpacesAvailable/README.md new file mode 100644 index 000000000..482b4f6ce --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Queue/QueueSpacesAvailable/README.md @@ -0,0 +1,9 @@ +This harness proves that QueueSpacesAvailable is memory safe. + +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 diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/QueueTakeMutexRecursive/Makefile.json b/FreeRTOS/Test/CBMC/proofs/Queue/QueueTakeMutexRecursive/Makefile.json new file mode 100644 index 000000000..210ead6b4 --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Queue/QueueTakeMutexRecursive/Makefile.json @@ -0,0 +1,62 @@ +# +# FreeRTOS memory safety proofs with CBMC. +# Copyright (C) 2019 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 +# + +{ + # This bound on queue size is needed to bound a loop in prvUnlockQueue + "PRV_UNLOCK_UNWINDING_BOUND": 4, + + # This is a bound on the timeout cycles + "QueueSemaphoreTake_BOUND": 4, + + "ENTRY": "QueueTakeMutexRecursive", + "CBMCFLAGS": [ + "--unwind {QueueSemaphoreTake_BOUND}", + "--unwindset prvUnlockQueue.0:{PRV_UNLOCK_UNWINDING_BOUND},prvUnlockQueue.1:{PRV_UNLOCK_UNWINDING_BOUND}", + "--signed-overflow-check", + "--pointer-overflow-check", + "--unsigned-overflow-check" + ], + "OBJS": [ + "$(ENTRY)_harness.goto", + "$(FREERTOS)/Source/queue.goto", + "$(FREERTOS)/Source/list.goto", + "$(FREERTOS)/Test/CBMC/proofs/CBMCStubLibrary/tasksStubs.goto" + ], + "DEF": [ + "configUSE_TRACE_FACILITY=0", + "configGENERATE_RUN_TIME_STATS=0", + "PRV_UNLOCK_UNWINDING_BOUND={PRV_UNLOCK_UNWINDING_BOUND}", + "QueueSemaphoreTake_BOUND={QueueSemaphoreTake_BOUND}" + ], + "INC": [ + "." + ], + "GENERATE_HEADER": [ + "queue_datastructure.h" + ] +} diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/QueueTakeMutexRecursive/QueueTakeMutexRecursive_harness.c b/FreeRTOS/Test/CBMC/proofs/Queue/QueueTakeMutexRecursive/QueueTakeMutexRecursive_harness.c new file mode 100644 index 000000000..9864321e0 --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Queue/QueueTakeMutexRecursive/QueueTakeMutexRecursive_harness.c @@ -0,0 +1,71 @@ +/* + * FreeRTOS memory safety proofs with CBMC. + * Copyright (C) 2019 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 "FreeRTOS.h" +#include "queue.h" +#include "tasksStubs.h" +#include "queue_datastructure.h" +#include "cbmc.h" + +QueueHandle_t xMutex; + +void vTaskInternalSetTimeOutState( TimeOut_t * const pxTimeOut ) +{ + /* QueueSemaphoreTake might be blocked to wait for + another process to release a token to the semaphore. + This is currently not in the CBMC model. Anyhow, + vTaskInternalSetTimeOutState is set a timeout for + QueueSemaphoreTake operation. We use this to model a successful + release during wait time. */ + UBaseType_t bound; + __CPROVER_assume((bound >= 0 && xMutex->uxLength >= bound)); + xMutex->uxMessagesWaiting = bound; +} + +BaseType_t xTaskGetSchedulerState( void ) { + BaseType_t ret; + __CPROVER_assume(ret != taskSCHEDULER_SUSPENDED); + return ret; +} + +void harness() { + uint8_t ucQueueType; + xMutex = xQueueCreateMutex(ucQueueType); + TickType_t xTicksToWait; + + /* Init task stub to make sure that the QueueSemaphoreTake_BOUND - 1 + loop iteration simulates a time out */ + vInitTaskCheckForTimeOut(0, QueueSemaphoreTake_BOUND - 1); + + if(xMutex){ + xMutex->cTxLock = PRV_UNLOCK_UNWINDING_BOUND - 1; + xMutex->cRxLock = PRV_UNLOCK_UNWINDING_BOUND - 1; + xMutex->uxMessagesWaiting = nondet_UBaseType_t(); + xQueueTakeMutexRecursive(xMutex, xTicksToWait); + } +} diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/QueueTakeMutexRecursive/README.md b/FreeRTOS/Test/CBMC/proofs/Queue/QueueTakeMutexRecursive/README.md new file mode 100644 index 000000000..4513147d9 --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Queue/QueueTakeMutexRecursive/README.md @@ -0,0 +1,23 @@ +Assuming that the parameter is valid mutex data structure and reasonable +bounded, this harness proves the memory safety of QueueTakeMutexRecursive. +Task pool and concurrency functions are abstracted away and replaced with +required stubs to drive coverage. + +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: + +* pvTaskIncrementMutexHeldCount +* vPortEnterCritical +* vPortExitCritical +* vPortGenerateSimulatedInterrupt +* vTaskMissedYield +* vTaskPlaceOnEventList +* vTaskPriorityDisinheritAfterTimeout +* vTaskSuspendAll +* xTaskGetCurrentTaskHandle +* xTaskPriorityDisinherit +* xTaskPriorityInherit +* xTaskRemoveFromEventList +* xTaskResumeAll diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/prvCopyDataToQueue/Configurations.json b/FreeRTOS/Test/CBMC/proofs/Queue/prvCopyDataToQueue/Configurations.json new file mode 100644 index 000000000..521839c3c --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Queue/prvCopyDataToQueue/Configurations.json @@ -0,0 +1,71 @@ +# +# FreeRTOS memory safety proofs with CBMC. +# Copyright (C) 2019 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": "prvCopyDataToQueue", + "CBMCFLAGS": [ + "--unwind 1", + "--signed-overflow-check", + "--pointer-overflow-check", + "--unsigned-overflow-check" + ], + "OBJS": [ + "$(ENTRY)_harness.goto", + "$(FREERTOS)/Source/queue.goto", + "$(FREERTOS)/Source/list.goto" + ], + "DEF": [ + { + "prvCopyDataToQueue_default" : [ + "'configPRECONDITION(X)=__CPROVER_assume(X)'", + "'mtCOVERAGE_TEST_MARKER()=__CPROVER_assert(1, \"Coverage marker\")'", + "configUSE_TRACE_FACILITY=0", + "configGENERATE_RUN_TIME_STATS=0", + "configUSE_MUTEXES=1" + + ] + }, + { + "prvCopyDataToQueue_noMutex" : [ + "'configPRECONDITION(X)=__CPROVER_assume(X)'", + "'mtCOVERAGE_TEST_MARKER()=__CPROVER_assert(1, \"Coverage marker\")'", + "configUSE_TRACE_FACILITY=0", + "configGENERATE_RUN_TIME_STATS=0", + "configUSE_MUTEXES=0", + "configUSE_RECURSIVE_MUTEXES=0" + ] + } + ], + "INC": [ + "." + ], + "GENERATE_HEADER":[ + "queue_datastructure.h" + ] +} + diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/prvCopyDataToQueue/README.md b/FreeRTOS/Test/CBMC/proofs/Queue/prvCopyDataToQueue/README.md new file mode 100644 index 000000000..ee6bc03e0 --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Queue/prvCopyDataToQueue/README.md @@ -0,0 +1,12 @@ +This harness proves the memory safety of the prvNotifyQueuSetContainer method. +It assumes that the queue is initalized to a valid datastructure. +The concurrency functions are abstracted away. + +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 +* xTaskPriorityDisinherit diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/prvCopyDataToQueue/prvCopyDataToQueue_harness.c b/FreeRTOS/Test/CBMC/proofs/Queue/prvCopyDataToQueue/prvCopyDataToQueue_harness.c new file mode 100644 index 000000000..80398bfa2 --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Queue/prvCopyDataToQueue/prvCopyDataToQueue_harness.c @@ -0,0 +1,54 @@ +/* + * FreeRTOS memory safety proofs with CBMC. + * Copyright (C) 2019 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 "FreeRTOS.h" +#include "queue.h" +#include "queue_init.h" +#include "cbmc.h" + +BaseType_t prvCopyDataToQueue( Queue_t * const pxQueue, const void *pvItemToQueue, const BaseType_t xPosition ); + +void harness(){ + QueueHandle_t xQueue = xUnconstrainedQueueBoundedItemSize(10); + + + if( xQueue ){ + void *pvItemToQueue = pvPortMalloc(xQueue->uxItemSize); + if( !pvItemToQueue ) + { + xQueue->uxItemSize = 0; + } + if(xQueue->uxItemSize == 0) + { + xQueue->uxQueueType = nondet_int8_t(); + } + BaseType_t xPosition; + prvCopyDataToQueue( xQueue, pvItemToQueue, xPosition ); + } + +} diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/prvNotifyQueueSetContainer/Configurations.json b/FreeRTOS/Test/CBMC/proofs/Queue/prvNotifyQueueSetContainer/Configurations.json new file mode 100644 index 000000000..516ea7df1 --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Queue/prvNotifyQueueSetContainer/Configurations.json @@ -0,0 +1,73 @@ +# +# FreeRTOS memory safety proofs with CBMC. +# Copyright (C) 2019 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": "prvNotifyQueueSetContainer", + "LOCK_BOUND": 2, + "CBMCFLAGS": [ + "--unwind 1", + "--signed-overflow-check", + "--pointer-overflow-check", + "--unsigned-overflow-check", + "--unwindset prvUnlockQueue.0:{LOCK_BOUND},prvUnlockQueue.1:{LOCK_BOUND}" + ], + "OBJS": [ + "$(ENTRY)_harness.goto", + "$(FREERTOS)/Source/queue.goto", + "$(FREERTOS)/Source/list.goto" + ], + "DEF": [ + { + "prvNotifyQueueSetContainer_Mutex" : [ + "'mtCOVERAGE_TEST_MARKER()=__CPROVER_assert(1, \"Coverage marker\")'", + "configUSE_TRACE_FACILITY=0", + "configGENERATE_RUN_TIME_STATS=0", + "configUSE_MUTEXES=1", + "configUSE_RECURSIVE_MUTEXES=1", + "configUSE_QUEUE_SETS=1" + + ] + }, + { + "prvNotifyQueueSetContainer_noMutex" : [ + "'mtCOVERAGE_TEST_MARKER()=__CPROVER_assert(1, \"Coverage marker\")'", + "configUSE_TRACE_FACILITY=0", + "configGENERATE_RUN_TIME_STATS=0", + "configUSE_MUTEXES=0", + "configUSE_RECURSIVE_MUTEXES=0", + "configUSE_QUEUE_SETS=1" + ] + } + ], + "INC": [ + "." + ], + "GENERATE_HEADER":[ + "queue_datastructure.h" + ] +} diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/prvNotifyQueueSetContainer/README.md b/FreeRTOS/Test/CBMC/proofs/Queue/prvNotifyQueueSetContainer/README.md new file mode 100644 index 000000000..6dddc4172 --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Queue/prvNotifyQueueSetContainer/README.md @@ -0,0 +1,14 @@ +This harness proves the memory safety of the prvNotifyQueuSetContainer method. +It assumes that the queue is initalized to a valid datastructure and added +to a QueueSet. The concurrency functions and task pool functions are abstracted +away. prvCopyDataToQueue is replaced with a stub checking the preconditions +for prvCopyDataToQueue to be sucessful. + +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 +* xTaskRemoveFromEventList diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/prvNotifyQueueSetContainer/prvNotifyQueueSetContainer_harness.c b/FreeRTOS/Test/CBMC/proofs/Queue/prvNotifyQueueSetContainer/prvNotifyQueueSetContainer_harness.c new file mode 100644 index 000000000..e9575adab --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Queue/prvNotifyQueueSetContainer/prvNotifyQueueSetContainer_harness.c @@ -0,0 +1,93 @@ +/* + * FreeRTOS memory safety proofs with CBMC. + * Copyright (C) 2019 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 "FreeRTOS.h" +#include "queue.h" +#include "queue_datastructure.h" +#include "cbmc.h" + +#ifndef LOCK_BOUND + #define LOCK_BOUND 4 +#endif + +BaseType_t prvNotifyQueueSetContainer( const Queue_t * const pxQueue, const BaseType_t xCopyPosition ); + +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(); + } +} + +QueueSetHandle_t xUnconstrainedQueueSet() +{ + UBaseType_t uxEventQueueLength = 2; + QueueSetHandle_t xSet = xQueueCreateSet(uxEventQueueLength); + if( xSet ) + { + xSet->cTxLock = nondet_int8_t(); + xSet->cRxLock = nondet_int8_t(); + xSet->uxMessagesWaiting = nondet_UBaseType_t(); + xSet->xTasksWaitingToReceive.uxNumberOfItems = nondet_UBaseType_t(); + xSet->xTasksWaitingToSend.uxNumberOfItems = nondet_UBaseType_t(); + } + return xSet; +} + +void harness(){ + UBaseType_t uxQueueLength; + UBaseType_t uxItemSize; + uint8_t ucQueueType; + __CPROVER_assume(uxQueueLength > 0); + __CPROVER_assume(uxItemSize < 10); + /* The implicit assumption for the QueueGenericCreate method is, + that there are no overflows in the computation and the inputs are safe. + There is no check for this in the code base */ + UBaseType_t upper_bound = portMAX_DELAY - sizeof(Queue_t); + __CPROVER_assume(uxItemSize < (upper_bound)/uxQueueLength); + QueueHandle_t xQueue = + xQueueGenericCreate(uxQueueLength, uxItemSize, ucQueueType); + if( xQueue ){ + xQueueAddToSet(xQueue, xUnconstrainedQueueSet()); + if(xQueue->pxQueueSetContainer) { + __CPROVER_assume(xQueue->pxQueueSetContainer->uxMessagesWaiting < xQueue->pxQueueSetContainer->uxLength); + BaseType_t xCopyPosition = nondet_BaseType_t(); + prvNotifyQueueSetContainer(xQueue, xCopyPosition ); + } + } +} diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/prvUnlockQueue/Configurations.json b/FreeRTOS/Test/CBMC/proofs/Queue/prvUnlockQueue/Configurations.json new file mode 100644 index 000000000..3d52cb481 --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Queue/prvUnlockQueue/Configurations.json @@ -0,0 +1,74 @@ +# +# FreeRTOS memory safety proofs with CBMC. +# Copyright (C) 2019 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": "prvUnlockQueue", + "LOCK_BOUND": 2, + "CBMCFLAGS": [ + "--unwind 1", + "--signed-overflow-check", + "--pointer-overflow-check", + "--unsigned-overflow-check", + "--unwindset prvUnlockQueue.0:{LOCK_BOUND},prvUnlockQueue.1:{LOCK_BOUND}" + ], + "OBJS": [ + "$(ENTRY)_harness.goto", + "$(FREERTOS)/Source/queue.goto", + "$(FREERTOS)/Source/list.goto" + ], + "DEF": [ + { + "prvUnlockQueue_noQueueSets" : [ + "'configPRECONDITION(X)=__CPROVER_assume(X)'", + "'mtCOVERAGE_TEST_MARKER()=__CPROVER_assert(1, \"Coverage marker\")'", + "configUSE_TRACE_FACILITY=0", + "configGENERATE_RUN_TIME_STATS=0", + "LOCK_BOUND={LOCK_BOUND}", + "configUSE_QUEUE_SETS=0" + + ] + }, + { + "prvUnlockQueue_QueueSets" : [ + "'configPRECONDITION(X)=__CPROVER_assume(X)'", + "'mtCOVERAGE_TEST_MARKER()=__CPROVER_assert(1, \"Coverage marker\")'", + "configUSE_TRACE_FACILITY=0", + "configGENERATE_RUN_TIME_STATS=0", + "LOCK_BOUND={LOCK_BOUND}", + "configUSE_QUEUE_SETS=1" + ] + } + ], + "INC": [ + "." + ], + "GENERATE_HEADER":[ + "queue_datastructure.h" + ] +} + diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/prvUnlockQueue/README.md b/FreeRTOS/Test/CBMC/proofs/Queue/prvUnlockQueue/README.md new file mode 100644 index 000000000..8cd98b22c --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Queue/prvUnlockQueue/README.md @@ -0,0 +1,12 @@ +This harness proves the memory safety of the prvUnlockQueue function. +It is abstracting away the prvCopyDataToQueue function and task pools and concurrency functions. + +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 +* vTaskMissedYield +* xTaskRemoveFromEventList diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/prvUnlockQueue/prvUnlockQueue_harness.c b/FreeRTOS/Test/CBMC/proofs/Queue/prvUnlockQueue/prvUnlockQueue_harness.c new file mode 100644 index 000000000..1db424998 --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Queue/prvUnlockQueue/prvUnlockQueue_harness.c @@ -0,0 +1,103 @@ +/* + * FreeRTOS memory safety proofs with CBMC. + * Copyright (C) 2019 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 "FreeRTOS.h" +#include "queue.h" +#include "queue_datastructure.h" + +#include "cbmc.h" + +#ifndef LOCK_BOUND + #define LOCK_BOUND 4 +#endif + +void prvUnlockQueue( Queue_t * const pxQueue ); + +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(); + } +} + +QueueSetHandle_t xUnconstrainedQueueSet() +{ + UBaseType_t uxEventQueueLength = 2; + QueueSetHandle_t xSet = xQueueCreateSet(uxEventQueueLength); + if( xSet ) + { + xSet->cTxLock = nondet_int8_t(); + 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, there is no chance for the proof to succeed*/ + __CPROVER_assume(xSet->uxMessagesWaiting < xSet->uxLength); + xSet->xTasksWaitingToSend.uxNumberOfItems = nondet_UBaseType_t(); + } + return xSet; +} + +void harness(){ + UBaseType_t uxQueueLength; + UBaseType_t uxItemSize; + uint8_t ucQueueType; + __CPROVER_assume(uxQueueLength > 0); + __CPROVER_assume(uxItemSize < 10); + /* The implicit assumption for the QueueGenericCreate method is, + that there are no overflows in the computation and the inputs are safe. + There is no check for this in the code base */ + UBaseType_t upper_bound = portMAX_DELAY - sizeof(Queue_t); + __CPROVER_assume(uxItemSize < (upper_bound)/uxQueueLength); + QueueHandle_t xQueue = + xQueueGenericCreate(uxQueueLength, uxItemSize, ucQueueType); + if(xQueue){ + xQueue->cTxLock = LOCK_BOUND - 1; + xQueue->cRxLock = LOCK_BOUND - 1; + 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, there is no chance for the proof 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 + prvUnlockQueue(xQueue); + } +} diff --git a/FreeRTOS/Test/CBMC/proofs/README.md b/FreeRTOS/Test/CBMC/proofs/README.md new file mode 100644 index 000000000..48fb7c48d --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/README.md @@ -0,0 +1 @@ +This directory contains the proofs checked by CBMC. For each entry point of FreeRTOS tested, there is a directory that contains the test harness and cbmc configuration information needed to check the proof.
\ No newline at end of file diff --git a/FreeRTOS/Test/CBMC/proofs/Task/TaskCheckForTimeOut/Makefile.json b/FreeRTOS/Test/CBMC/proofs/Task/TaskCheckForTimeOut/Makefile.json new file mode 100644 index 000000000..8b2904e30 --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Task/TaskCheckForTimeOut/Makefile.json @@ -0,0 +1,49 @@ +# +# FreeRTOS memory safety proofs with CBMC. +# Copyright (C) 2019 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": "TaskCheckForTimeOut", + "DEF": + [ + "FREERTOS_MODULE_TEST", + "'mtCOVERAGE_TEST_MARKER()=__CPROVER_assert(1, \"Coverage marker\")'" + ], + "CBMCFLAGS": + [ + "--unwind 1" + ], + "OBJS": + [ + "$(ENTRY)_harness.goto", + "$(FREERTOS)/Source/tasks.goto" + ], + "INC": + [ + "$(FREERTOS)/Test/CBMC/proofs/Task/TaskCheckForTimeOut/" + ] +} diff --git a/FreeRTOS/Test/CBMC/proofs/Task/TaskCheckForTimeOut/README.md b/FreeRTOS/Test/CBMC/proofs/Task/TaskCheckForTimeOut/README.md new file mode 100644 index 000000000..5550f59d1 --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Task/TaskCheckForTimeOut/README.md @@ -0,0 +1,10 @@ +This proof demonstrates the memory safety of the TaskCheckForTimeOut function. +We assume `pxTimeOut`, `pxTicksToWait` and `pxCurrentTCB` to be non-NULL. + +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 diff --git a/FreeRTOS/Test/CBMC/proofs/Task/TaskCheckForTimeOut/TaskCheckForTimeOut_harness.c b/FreeRTOS/Test/CBMC/proofs/Task/TaskCheckForTimeOut/TaskCheckForTimeOut_harness.c new file mode 100644 index 000000000..d78189d3c --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Task/TaskCheckForTimeOut/TaskCheckForTimeOut_harness.c @@ -0,0 +1,54 @@ +/* + * FreeRTOS memory safety proofs with CBMC. + * Copyright (C) 2019 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" + +BaseType_t xPrepareCurrentTCB( void ); + +/* + * The function requires that the function arguments `pxTimeOut` and + * `pxTicksToWait` and the global variable `pxCurrentTCB` are not + * NULL. + */ +void harness() +{ + UBaseType_t xTasksPrepared; + TimeOut_t pxTimeOut; + TickType_t pxTicksToWait; + + xTasksPrepared = xPrepareCurrentTCB(); + + if ( xTasksPrepared != pdFAIL ) + { + xTaskCheckForTimeOut( &pxTimeOut, &pxTicksToWait ); + } +} diff --git a/FreeRTOS/Test/CBMC/proofs/Task/TaskCheckForTimeOut/tasks_test_access_functions.h b/FreeRTOS/Test/CBMC/proofs/Task/TaskCheckForTimeOut/tasks_test_access_functions.h new file mode 100644 index 000000000..926986b35 --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Task/TaskCheckForTimeOut/tasks_test_access_functions.h @@ -0,0 +1,51 @@ +/* + * FreeRTOS memory safety proofs with CBMC. + * Copyright (C) 2019 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 "cbmc.h" + +/* + * We allocate a TCB and set some members to basic values + */ +TaskHandle_t xUnconstrainedTCB( void ) +{ + TCB_t * pxTCB = pvPortMalloc( sizeof( TCB_t ) ); + + return pxTCB; +} + +/* + * We just need to allocate a totally unconstrained TCB + */ +BaseType_t xPrepareCurrentTCB( void ) +{ + __CPROVER_assert_zero_allocation(); + + pxCurrentTCB = xUnconstrainedTCB(); + + return pxCurrentTCB == NULL ? pdFAIL : pdPASS; +} diff --git a/FreeRTOS/Test/CBMC/proofs/Task/TaskCreate/Makefile.json b/FreeRTOS/Test/CBMC/proofs/Task/TaskCreate/Makefile.json new file mode 100644 index 000000000..71aac7719 --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Task/TaskCreate/Makefile.json @@ -0,0 +1,52 @@ +# +# FreeRTOS memory safety proofs with CBMC. +# Copyright (C) 2019 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": "TaskCreate", + "DEF": + [ + "STACK_DEPTH=10", + "FREERTOS_MODULE_TEST", + "'mtCOVERAGE_TEST_MARKER()=__CPROVER_assert(1, \"Coverage marker\")'" + ], + "CBMCFLAGS": + [ + "--unwind 1", + "--unwindset prvInitialiseNewTask.0:16,prvInitialiseNewTask.1:4,prvInitialiseTaskLists.0:8" + ], + "OBJS": + [ + "$(ENTRY)_harness.goto", + "$(FREERTOS)/Source/tasks.goto", + "$(FREERTOS)/Source/list.goto" + ], + "INC": + [ + "$(FREERTOS)/Test/CBMC/proofs/Task/TaskCreate/" + ] +} diff --git a/FreeRTOS/Test/CBMC/proofs/Task/TaskCreate/README.md b/FreeRTOS/Test/CBMC/proofs/Task/TaskCreate/README.md new file mode 100644 index 000000000..39a275a7d --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Task/TaskCreate/README.md @@ -0,0 +1,22 @@ +This proof demonstrates the memory safety of the TaskCreate function. +We initialize task lists, but we set other data structures to +unconstrained (arbitrary) values, including the data structures +`pxCurrentTCB`, `uxCurrentNumberOfTasks`, `pcName` and `pxCreateTask`. +STACK_DEPTH is set to a fixed number (10) since it is not possible to +specify a range. + +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: + +* prvTraceGetObjectHandle +* prvTraceGetTaskNumber +* prvTraceSetObjectName +* prvTraceSetPriorityProperty +* prvTraceStoreKernelCall +* prvTraceStoreTaskReady +* pxPortInitialiseStack +* vPortEnterCritical +* vPortExitCritical +* vPortGenerateSimulatedInterrupt diff --git a/FreeRTOS/Test/CBMC/proofs/Task/TaskCreate/TaskCreate_harness.c b/FreeRTOS/Test/CBMC/proofs/Task/TaskCreate/TaskCreate_harness.c new file mode 100644 index 000000000..d86a27639 --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Task/TaskCreate/TaskCreate_harness.c @@ -0,0 +1,63 @@ +/* + * FreeRTOS memory safety proofs with CBMC. + * Copyright (C) 2019 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" + +void vNondetSetCurrentTCB( void ); +void vSetGlobalVariables( void ); +void vPrepareTaskLists( void ); +TaskHandle_t *pxNondetSetTaskHandle( void ); +char *pcNondetSetString( size_t xSizeLength ); + +void harness() +{ + TaskFunction_t pxTaskCode; + char * pcName; + configSTACK_DEPTH_TYPE usStackDepth = STACK_DEPTH; + void * pvParameters; + UBaseType_t uxPriority; + TaskHandle_t * pxCreatedTask; + + vNondetSetCurrentTCB(); + vSetGlobalVariables(); + vPrepareTaskLists(); + + pxCreatedTask = pxNondetSetTaskHandle(); + pcName = pcNondetSetString( configMAX_TASK_NAME_LEN ); + + xTaskCreate(pxTaskCode, + pcName, + usStackDepth, + pvParameters, + uxPriority, + pxCreatedTask ); +} diff --git a/FreeRTOS/Test/CBMC/proofs/Task/TaskCreate/tasks_test_access_functions.h b/FreeRTOS/Test/CBMC/proofs/Task/TaskCreate/tasks_test_access_functions.h new file mode 100644 index 000000000..9e48040c7 --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Task/TaskCreate/tasks_test_access_functions.h @@ -0,0 +1,84 @@ +/* + * FreeRTOS memory safety proofs with CBMC. + * Copyright (C) 2019 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 "cbmc.h" + +/* + * Our stub for pvPortMalloc in cbmc.h nondeterministically chooses + * either to return NULL or to allocate the requested memory. + */ +void vNondetSetCurrentTCB( void ) +{ + pxCurrentTCB = pvPortMalloc( sizeof(TCB_t) ); +} +/* + * We just require task lists to be initialized for this proof + */ +void vPrepareTaskLists( void ) +{ + __CPROVER_assert_zero_allocation(); + + prvInitialiseTaskLists(); +} + +/* + * We set the values of relevant global + * variables to nondeterministic values + */ +void vSetGlobalVariables( void ) +{ + xSchedulerRunning = nondet_basetype(); + uxCurrentNumberOfTasks = nondet_ubasetype(); +} + +/* + * pvPortMalloc is nondeterministic by definition, thus we do not need + * to check for NULL allocation in this function + */ +TaskHandle_t *pxNondetSetTaskHandle( void ) +{ + TaskHandle_t *pxNondetTaskHandle = pvPortMalloc( sizeof(TaskHandle_t) ); + return pxNondetTaskHandle; +} + +/* + * Tries to allocate a string of size xStringLength and sets the string + * to be terminated using a nondeterministic index if allocation was successful + */ +char *pcNondetSetString( size_t xStringLength ) +{ + char *pcName = pvPortMalloc( xStringLength ); + + if ( pcName != NULL ) { + size_t uNondetIndex; + __CPROVER_assume( uNondetIndex < xStringLength ); + pcName[uNondetIndex] = '\0'; + } + + return pcName; +} diff --git a/FreeRTOS/Test/CBMC/proofs/Task/TaskDelay/Configurations.json b/FreeRTOS/Test/CBMC/proofs/Task/TaskDelay/Configurations.json new file mode 100644 index 000000000..5061e8e8a --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Task/TaskDelay/Configurations.json @@ -0,0 +1,68 @@ +# +# FreeRTOS memory safety proofs with CBMC. +# Copyright (C) 2019 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": "TaskDelay", + "DEF": + [ + { "default" : + [ + "FREERTOS_MODULE_TEST", + "PENDED_TICKS=1", + "'mtCOVERAGE_TEST_MARKER()=__CPROVER_assert(1, \"Coverage marker\")'", + "configUSE_TRACE_FACILITY=0", + "configGENERATE_RUN_TIME_STATS=0" + ] + }, + { "vTaskSuspend0" : + [ + "FREERTOS_MODULE_TEST", + "PENDED_TICKS=1", + "'mtCOVERAGE_TEST_MARKER()=__CPROVER_assert(1, \"Coverage marker\")'", + "configUSE_TRACE_FACILITY=0", + "configGENERATE_RUN_TIME_STATS=0", + "INCLUDE_vTaskSuspend=0" + ] + } + ], + "CBMCFLAGS": + [ + "--unwind 1", + "--unwindset prvInitialiseTaskLists.0:8,vListInsert.0:4" + ], + "OBJS": + [ + "$(ENTRY)_harness.goto", + "$(FREERTOS)/Source/tasks.goto", + "$(FREERTOS)/Source/list.goto" + ], + "INC": + [ + "$(FREERTOS)/Test/CBMC/proofs/Task/TaskDelay/" + ] +} diff --git a/FreeRTOS/Test/CBMC/proofs/Task/TaskDelay/README.md b/FreeRTOS/Test/CBMC/proofs/Task/TaskDelay/README.md new file mode 100644 index 000000000..f5cb3552d --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Task/TaskDelay/README.md @@ -0,0 +1,21 @@ +This proof demonstrates the memory safety of the TaskDelay function. We assume +that `pxCurrentTCB` is initialized and inserted in one of the ready tasks lists +(with and without another task in the same list). We abstract function +`xTaskResumeAll` by assuming that `xPendingReadyList` is empty and +`xPendedTicks` is `0`. Finally, we assume nondeterministic values for global +variables `xTickCount` and `xNextTaskUnblockTime`, and `pdFALSE` for +`uxSchedulerSuspended` (to avoid assertion failure). + +Configurations available: + + * `default`: The default configuration. + * `useTickHook1`: The default configuration with `INCLUDE_vTaskSuspend=0` + +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 diff --git a/FreeRTOS/Test/CBMC/proofs/Task/TaskDelay/TaskDelay_harness.c b/FreeRTOS/Test/CBMC/proofs/Task/TaskDelay/TaskDelay_harness.c new file mode 100644 index 000000000..2ef21dedb --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Task/TaskDelay/TaskDelay_harness.c @@ -0,0 +1,65 @@ +/* + * FreeRTOS memory safety proofs with CBMC. + * Copyright (C) 2019 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" + +void vSetGlobalVariables( void ); +BaseType_t xPrepareTaskLists( void ); +BaseType_t xTaskResumeAllStub( void ); + +/* + * This is a trick to overcome the "redefined twice" error + * when stubbing out the `xTaskResumeAll` function in the header + */ +BaseType_t xTaskResumeAll( void ) { + return xTaskResumeAllStub(); +} + +/* + * The harness test first calls two functions included in the tasks.c file + * that initialize the task lists and other global variables + */ +void harness() +{ + TickType_t xTicksToDelay; + BaseType_t xTasksPrepared; + + vSetGlobalVariables(); + xTasksPrepared = xPrepareTaskLists(); + + if ( xTasksPrepared != pdFAIL ) + { + vTaskDelay( xTicksToDelay ); + } +} + + diff --git a/FreeRTOS/Test/CBMC/proofs/Task/TaskDelay/tasks_test_access_functions.h b/FreeRTOS/Test/CBMC/proofs/Task/TaskDelay/tasks_test_access_functions.h new file mode 100644 index 000000000..b6b1210b0 --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Task/TaskDelay/tasks_test_access_functions.h @@ -0,0 +1,145 @@ +/* + * FreeRTOS memory safety proofs with CBMC. + * Copyright (C) 2019 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 "cbmc.h" + +/* + * We allocate a TCB and set some members to basic values + */ +TaskHandle_t xUnconstrainedTCB( void ) +{ + TCB_t * pxTCB = pvPortMalloc(sizeof(TCB_t)); + + if ( pxTCB == NULL ) + return NULL; + + __CPROVER_assume( pxTCB->uxPriority < configMAX_PRIORITIES ); + + vListInitialiseItem( &( pxTCB->xStateListItem ) ); + vListInitialiseItem( &( pxTCB->xEventListItem ) ); + + listSET_LIST_ITEM_OWNER( &( pxTCB->xStateListItem ), pxTCB ); + listSET_LIST_ITEM_OWNER( &( pxTCB->xEventListItem ), pxTCB ); + + if ( nondet_bool() ) + { + listSET_LIST_ITEM_VALUE( &( pxTCB->xStateListItem ), pxTCB->uxPriority ); + } + else + { + listSET_LIST_ITEM_VALUE( &( pxTCB->xStateListItem ), portMAX_DELAY ); + } + + if ( nondet_bool() ) + { + listSET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ), ( TickType_t ) configMAX_PRIORITIES - ( TickType_t ) pxTCB->uxPriority ); + } + else + { + listSET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ), portMAX_DELAY ); + } + return pxTCB; +} + +/* + * We set the values of relevant global variables to + * nondeterministic values, except for `uxSchedulerSuspended` + * which is set to 0 (to pass through the assertion) + */ + +void vSetGlobalVariables( void ) +{ + uxSchedulerSuspended = pdFALSE; + xTickCount = nondet_ticktype(); + xNextTaskUnblockTime = nondet_ticktype(); +} + +/* + * We initialise and fill the task lists so coverage is optimal. + * This initialization is not guaranteed to be minimal, but it + * is quite efficient and it serves the same purpose + */ +BaseType_t xPrepareTaskLists( void ) +{ + TCB_t * pxTCB = NULL; + + __CPROVER_assert_zero_allocation(); + + prvInitialiseTaskLists(); + + /* The current task will be moved to the delayed list */ + pxCurrentTCB = xUnconstrainedTCB(); + if ( pxCurrentTCB == NULL ) + { + return pdFAIL; + } + vListInsert( &pxReadyTasksLists[ pxCurrentTCB->uxPriority ], &( pxCurrentTCB->xStateListItem ) ); + + /* + * Nondeterministic insertion of a task in the ready tasks list + * guarantees coverage in line 5104 (tasks.c) + */ + if ( nondet_bool() ) + { + pxTCB = xUnconstrainedTCB(); + if ( pxTCB == NULL ) + { + return pdFAIL; + } + vListInsert( &pxReadyTasksLists[ pxTCB->uxPriority ], &( pxTCB->xStateListItem ) ); + + /* Use of this macro ensures coverage on line 185 (list.c) */ + listGET_OWNER_OF_NEXT_ENTRY( pxTCB , &pxReadyTasksLists[ pxTCB->uxPriority ] ); + } + + + return pdPASS; +} + +/* + * We stub out `xTaskResumeAll` including the assertion and change on + * variables `uxSchedulerSuspended`. We assume that `xPendingReadyList` + * is empty to avoid the first loop, and xPendedTicks to avoid the second + * one. Finally, we return a nondeterministic value (overapproximation) + */ +BaseType_t xTaskResumeAllStub( void ) +{ + BaseType_t xAlreadyYielded; + + configASSERT( uxSchedulerSuspended ); + + taskENTER_CRITICAL(); + { + --uxSchedulerSuspended; + __CPROVER_assert( listLIST_IS_EMPTY( &xPendingReadyList ), "Pending ready tasks list not empty." ); + __CPROVER_assert( xPendedTicks == 0 , "xPendedTicks is not equal to zero."); + } + taskEXIT_CRITICAL(); + + return xAlreadyYielded; +} diff --git a/FreeRTOS/Test/CBMC/proofs/Task/TaskDelete/Makefile.json b/FreeRTOS/Test/CBMC/proofs/Task/TaskDelete/Makefile.json new file mode 100644 index 000000000..bce77b851 --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Task/TaskDelete/Makefile.json @@ -0,0 +1,55 @@ +# +# FreeRTOS memory safety proofs with CBMC. +# Copyright (C) 2019 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": "TaskDelete", + "DEF": + [ + "FREERTOS_MODULE_TEST", + "'mtCOVERAGE_TEST_MARKER()=__CPROVER_assert(1, \"Coverage marker\")'", + "STACK_DEPTH=10", + "configUSE_TRACE_FACILITY=0", + "configGENERATE_RUN_TIME_STATS=0" + ], + "CBMCFLAGS": + [ + "--unwind 1", + "--unwindset prvInitialiseTaskLists.0:8,vListInsert.0:3" + + ], + "OBJS": + [ + "$(ENTRY)_harness.goto", + "$(FREERTOS)/Source/tasks.goto", + "$(FREERTOS)/Source/list.goto" + ], + "INC": + [ + "$(FREERTOS)/Test/CBMC/proofs/Task/TaskDelete/" + ] +} diff --git a/FreeRTOS/Test/CBMC/proofs/Task/TaskDelete/README.md b/FreeRTOS/Test/CBMC/proofs/Task/TaskDelete/README.md new file mode 100644 index 000000000..9b9753043 --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Task/TaskDelete/README.md @@ -0,0 +1,19 @@ +This proof demonstrates the memory safety of the TaskDelete function. The +initialization for the task to be delete and `pxCurrentTCB` is quite similar +(since the task handle may be NULL, and in that case `pxCurrentTCB` is used). +The task to be deleted requires the stack in the task control block to be +allocated, and the flag for static allocation to be properly set (i.e., valid +values as defined by the macros) Task lists are initialized with these tasks +and nondet. filled with a few more items. We assume a nondet. value for +`xSchedulerRunning`. + +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: + +* vPortCloseRunningThread +* vPortDeleteThread +* vPortEnterCritical +* vPortExitCritical +* vPortGenerateSimulatedInterrupt diff --git a/FreeRTOS/Test/CBMC/proofs/Task/TaskDelete/TaskDelete_harness.c b/FreeRTOS/Test/CBMC/proofs/Task/TaskDelete/TaskDelete_harness.c new file mode 100644 index 000000000..4bc5cc7cf --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Task/TaskDelete/TaskDelete_harness.c @@ -0,0 +1,54 @@ +/* + * FreeRTOS memory safety proofs with CBMC. + * Copyright (C) 2019 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" + +void vSetGlobalVariables(); +BaseType_t xPrepareTaskLists( TaskHandle_t * xTask ); + +/* + * The harness test first calls two functions included in the tasks.c file + * that initialize the task lists and other global variables + */ +void harness() +{ + TaskHandle_t xTaskToDelete; + BaseType_t xTasksPrepared; + + vSetGlobalVariables(); + xTasksPrepared = xPrepareTaskLists( &xTaskToDelete ); + + if ( xTasksPrepared != pdFAIL ) + { + vTaskDelete( xTaskToDelete ); + } +} diff --git a/FreeRTOS/Test/CBMC/proofs/Task/TaskDelete/tasks_test_access_functions.h b/FreeRTOS/Test/CBMC/proofs/Task/TaskDelete/tasks_test_access_functions.h new file mode 100644 index 000000000..67c367cd7 --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Task/TaskDelete/tasks_test_access_functions.h @@ -0,0 +1,172 @@ +/* + * FreeRTOS memory safety proofs with CBMC. + * Copyright (C) 2019 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 "cbmc.h" + +/* + * We allocate a TCB and set some members to basic values + */ +TaskHandle_t xUnconstrainedTCB( void ) +{ + TCB_t * pxTCB = pvPortMalloc(sizeof(TCB_t)); + uint8_t ucStaticAllocationFlag; + + if ( pxTCB == NULL ) + return NULL; + + __CPROVER_assume( pxTCB->uxPriority < configMAX_PRIORITIES ); + + vListInitialiseItem( &( pxTCB->xStateListItem ) ); + vListInitialiseItem( &( pxTCB->xEventListItem ) ); + + listSET_LIST_ITEM_OWNER( &( pxTCB->xStateListItem ), pxTCB ); + listSET_LIST_ITEM_OWNER( &( pxTCB->xEventListItem ), pxTCB ); + + if ( nondet_bool() ) + { + listSET_LIST_ITEM_VALUE( &( pxTCB->xStateListItem ), pxTCB->uxPriority ); + } + else + { + listSET_LIST_ITEM_VALUE( &( pxTCB->xStateListItem ), portMAX_DELAY ); + } + + if ( nondet_bool() ) + { + listSET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ), ( TickType_t ) configMAX_PRIORITIES - ( TickType_t ) pxTCB->uxPriority ); + } + else + { + listSET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ), portMAX_DELAY ); + } + + pxTCB->pxStack = ( StackType_t * ) pvPortMalloc( ( ( ( size_t ) STACK_DEPTH ) * sizeof( StackType_t ) ) ); + if ( pxTCB->pxStack == NULL ) + { + vPortFree( pxTCB ); + return NULL; + } + + __CPROVER_assume( ucStaticAllocationFlag <= tskSTATICALLY_ALLOCATED_STACK_AND_TCB ); + __CPROVER_assume( ucStaticAllocationFlag >= tskDYNAMICALLY_ALLOCATED_STACK_AND_TCB ); + pxTCB->ucStaticallyAllocated = ucStaticAllocationFlag; + + return pxTCB; +} + +/* + * We set the values of relevant global + * variables to nondeterministic values + */ +void vSetGlobalVariables() +{ + xSchedulerRunning = nondet_basetype(); +} + +/* + * We initialise and fill the task lists so coverage is optimal. + * This initialization is not guaranteed to be minimal, but it + * is quite efficient and it serves the same purpose + */ +BaseType_t xPrepareTaskLists( TaskHandle_t * xTask ) +{ + TCB_t * pxTCB = NULL; + + __CPROVER_assert_zero_allocation(); + + prvInitialiseTaskLists(); + + /* + * The task handle passed to TaskDelete can be NULL. In that case, the + * task to delete is the one in `pxCurrentTCB`, see the macro `prvGetTCBFromHandle` + * in line 1165 (tasks.c) for reference. For that reason, we provide a similar + * initialization for an arbitrary task `pxTCB` and `pxCurrentTCB`. + */ + + pxTCB = xUnconstrainedTCB(); + if ( pxTCB != NULL ) + { + if ( nondet_bool() ) + { + TCB_t * pxOtherTCB; + pxOtherTCB = xUnconstrainedTCB(); + /* + * Nondeterministic insertion of another TCB in the same list + * to guarantee coverage in line 1174 (tasks.c) + */ + if ( pxOtherTCB != NULL ) + { + vListInsert( &xPendingReadyList, &( pxOtherTCB->xStateListItem ) ); + } + } + vListInsert( &xPendingReadyList, &( pxTCB->xStateListItem ) ); + + /* + * Nondeterministic insertion of an event list item to guarantee + * coverage in lines 1180-1184 (tasks.c) + */ + if ( nondet_bool() ) + { + vListInsert( pxDelayedTaskList, &( pxTCB->xEventListItem ) ); + } + } + + /* Note that `*xTask = NULL` can happen here, but this is fine -- `pxCurrentTCB` will be used instead */ + *xTask = pxTCB; + + /* + * `pxCurrentTCB` must be initialized the same way as the previous task, but an + * allocation failure cannot happen in this case (i.e., if the previous task is NULL) + */ + pxCurrentTCB = xUnconstrainedTCB(); + if ( pxCurrentTCB == NULL ) + { + return pdFAIL; + } + + if ( nondet_bool() ) + { + TCB_t * pxOtherTCB; + pxOtherTCB = xUnconstrainedTCB(); + if ( pxOtherTCB != NULL ) + { + vListInsert( &pxReadyTasksLists[ pxOtherTCB->uxPriority ], &( pxOtherTCB->xStateListItem ) ); + } + } + vListInsert( &pxReadyTasksLists[ pxCurrentTCB->uxPriority ], &( pxCurrentTCB->xStateListItem ) ); + + /* Use of this macro ensures coverage on line 185 (list.c) */ + listGET_OWNER_OF_NEXT_ENTRY( pxCurrentTCB , &pxReadyTasksLists[ pxCurrentTCB->uxPriority ] ); + + if ( nondet_bool() ) + { + vListInsert( pxDelayedTaskList, &( pxCurrentTCB->xEventListItem ) ); + } + + return pdPASS; +} diff --git a/FreeRTOS/Test/CBMC/proofs/Task/TaskGetCurrentTaskHandle/Makefile.json b/FreeRTOS/Test/CBMC/proofs/Task/TaskGetCurrentTaskHandle/Makefile.json new file mode 100644 index 000000000..d461b1dd3 --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Task/TaskGetCurrentTaskHandle/Makefile.json @@ -0,0 +1,51 @@ +# +# FreeRTOS memory safety proofs with CBMC. +# Copyright (C) 2019 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": "TaskGetCurrentTaskHandle", + "DEF": + [ + "FREERTOS_MODULE_TEST", + "'mtCOVERAGE_TEST_MARKER()=__CPROVER_assert(1, \"Coverage marker\")'" + ], + "CBMCFLAGS": + [ + "--unwind 1" + ], + "OBJS": + [ + "$(ENTRY)_harness.goto", + "$(FREERTOS)/Source/tasks.goto", + "$(FREERTOS)/Source/list.goto" + ], + "INC": + [ + "$(FREERTOS)/Source/", + "$(FREERTOS)/Test/CBMC/proofs/Task/TaskGetCurrentTaskHandle/" + ] +} diff --git a/FreeRTOS/Test/CBMC/proofs/Task/TaskGetCurrentTaskHandle/README.md b/FreeRTOS/Test/CBMC/proofs/Task/TaskGetCurrentTaskHandle/README.md new file mode 100644 index 000000000..af9280495 --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Task/TaskGetCurrentTaskHandle/README.md @@ -0,0 +1,6 @@ +This proof demonstrates the memory safety of the TaskGetCurrentTaskHandle +function. We assume that `pxCurrentTCB` is not NULL and we check that the +return value is not NULL. + +This proof is a work-in-progress. Proof assumptions are described in +the harness. diff --git a/FreeRTOS/Test/CBMC/proofs/Task/TaskGetCurrentTaskHandle/TaskGetCurrentTaskHandle_harness.c b/FreeRTOS/Test/CBMC/proofs/Task/TaskGetCurrentTaskHandle/TaskGetCurrentTaskHandle_harness.c new file mode 100644 index 000000000..dac3c6685 --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Task/TaskGetCurrentTaskHandle/TaskGetCurrentTaskHandle_harness.c @@ -0,0 +1,54 @@ +/* + * FreeRTOS memory safety proofs with CBMC. + * Copyright (C) 2019 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" + +BaseType_t xPrepareCurrentTCB( void ); + +/* + * We set pxCurrentTCB to an unconstrained TCB. Then we call + * xTaskGetCurrentTaskHandle() and check the return value is not NULL + */ +void harness() +{ + TaskHandle_t xTask; + BaseType_t xTasksPrepared; + + xTasksPrepared = xPrepareCurrentTCB(); + + if ( xTasksPrepared != pdFAIL ) + { + xTask = xTaskGetCurrentTaskHandle(); + + __CPROVER_assert( xTask != NULL , "Current task handle is NULL!"); + } +} diff --git a/FreeRTOS/Test/CBMC/proofs/Task/TaskGetCurrentTaskHandle/tasks_test_access_functions.h b/FreeRTOS/Test/CBMC/proofs/Task/TaskGetCurrentTaskHandle/tasks_test_access_functions.h new file mode 100644 index 000000000..29505148d --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Task/TaskGetCurrentTaskHandle/tasks_test_access_functions.h @@ -0,0 +1,58 @@ +/* + * FreeRTOS memory safety proofs with CBMC. + * Copyright (C) 2019 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 "cbmc.h" + +/* + * We allocate a TCB and set some members to basic values + */ +TaskHandle_t xUnconstrainedTCB( void ) +{ + TCB_t * pxTCB = pvPortMalloc(sizeof(TCB_t)); + + if ( pxTCB == NULL ) + return NULL; + + return pxTCB; +} + +/* + * We just need to allocate a totally unconstrained TCB + */ +BaseType_t xPrepareCurrentTCB( void ) +{ + __CPROVER_assert_zero_allocation(); + + pxCurrentTCB = xUnconstrainedTCB(); + if ( pxCurrentTCB == NULL ) + { + return pdFAIL; + } + + return pdPASS; +} diff --git a/FreeRTOS/Test/CBMC/proofs/Task/TaskGetSchedulerState/Makefile.json b/FreeRTOS/Test/CBMC/proofs/Task/TaskGetSchedulerState/Makefile.json new file mode 100644 index 000000000..633e659cd --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Task/TaskGetSchedulerState/Makefile.json @@ -0,0 +1,49 @@ +# +# FreeRTOS memory safety proofs with CBMC. +# Copyright (C) 2019 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": "TaskGetSchedulerState", + "DEF": + [ + "FREERTOS_MODULE_TEST", + "'mtCOVERAGE_TEST_MARKER()=__CPROVER_assert(1, \"Coverage marker\")'" + ], + "CBMCFLAGS": + [ + "--unwind 1" + ], + "OBJS": + [ + "$(ENTRY)_harness.goto", + "$(FREERTOS)/Source/tasks.goto" + ], + "INC": + [ + "$(FREERTOS)/Test/CBMC/proofs/Task/TaskGetSchedulerState/" + ] +} diff --git a/FreeRTOS/Test/CBMC/proofs/Task/TaskGetSchedulerState/README.md b/FreeRTOS/Test/CBMC/proofs/Task/TaskGetSchedulerState/README.md new file mode 100644 index 000000000..d7b732bdd --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Task/TaskGetSchedulerState/README.md @@ -0,0 +1,6 @@ +This proof demonstrates the memory safety of the TaskGetSchedulerState function. +We assume `xSchedulerRunning` and `uxSchedulerSuspended` to be nondeterministic values. + +This proof is a work-in-progress. Proof assumptions are described in +the harness. + diff --git a/FreeRTOS/Test/CBMC/proofs/Task/TaskGetSchedulerState/TaskGetSchedulerState_harness.c b/FreeRTOS/Test/CBMC/proofs/Task/TaskGetSchedulerState/TaskGetSchedulerState_harness.c new file mode 100644 index 000000000..557fb598e --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Task/TaskGetSchedulerState/TaskGetSchedulerState_harness.c @@ -0,0 +1,48 @@ +/* + * FreeRTOS memory safety proofs with CBMC. + * Copyright (C) 2019 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" + +void vSetGlobalVariables( void ); + +/* + * We just require scheduler flags to be nondeterministic + * values before calling `xTaskGetSchedulerState` + */ +void harness() +{ + BaseType_t xResult; + + vSetGlobalVariables(); + + xResult = xTaskGetSchedulerState(); +} diff --git a/FreeRTOS/Test/CBMC/proofs/Task/TaskGetSchedulerState/tasks_test_access_functions.h b/FreeRTOS/Test/CBMC/proofs/Task/TaskGetSchedulerState/tasks_test_access_functions.h new file mode 100644 index 000000000..7e1b29489 --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Task/TaskGetSchedulerState/tasks_test_access_functions.h @@ -0,0 +1,37 @@ +/* + * FreeRTOS memory safety proofs with CBMC. + * Copyright (C) 2019 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 + */ + +/* + * We set the values of relevant global + * variables to nondeterministic values + */ +void vSetGlobalVariables( void ) +{ + xSchedulerRunning = nondet_basetype(); + uxSchedulerSuspended = nondet_ubasetype(); +} diff --git a/FreeRTOS/Test/CBMC/proofs/Task/TaskGetTaskNumber/Makefile.json b/FreeRTOS/Test/CBMC/proofs/Task/TaskGetTaskNumber/Makefile.json new file mode 100644 index 000000000..909ada3de --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Task/TaskGetTaskNumber/Makefile.json @@ -0,0 +1,49 @@ +# +# FreeRTOS memory safety proofs with CBMC. +# Copyright (C) 2019 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": "TaskGetTaskNumber", + "DEF": + [ + "FREERTOS_MODULE_TEST", + "'mtCOVERAGE_TEST_MARKER()=__CPROVER_assert(1, \"Coverage marker\")'" + ], + "CBMCFLAGS": + [ + "--unwind 1" + ], + "OBJS": + [ + "$(ENTRY)_harness.goto", + "$(FREERTOS)/Source/tasks.goto" + ], + "INC": + [ + "$(FREERTOS)/Test/CBMC/proofs/Task/TaskGetTaskNumber/" + ] +} diff --git a/FreeRTOS/Test/CBMC/proofs/Task/TaskGetTaskNumber/README.md b/FreeRTOS/Test/CBMC/proofs/Task/TaskGetTaskNumber/README.md new file mode 100644 index 000000000..3c35737aa --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Task/TaskGetTaskNumber/README.md @@ -0,0 +1,5 @@ +This proof demonstrates the memory safety of the TaskGetTaskNumber function. +No assumption is required since the function accepts a NULL value for the task handle. + +This proof is a work-in-progress. Proof assumptions are described in +the harness. diff --git a/FreeRTOS/Test/CBMC/proofs/Task/TaskGetTaskNumber/TaskGetTaskNumber_harness.c b/FreeRTOS/Test/CBMC/proofs/Task/TaskGetTaskNumber/TaskGetTaskNumber_harness.c new file mode 100644 index 000000000..6df4fe393 --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Task/TaskGetTaskNumber/TaskGetTaskNumber_harness.c @@ -0,0 +1,49 @@ +/* + * FreeRTOS memory safety proofs with CBMC. + * Copyright (C) 2019 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" + +void vPrepareTask( TaskHandle_t * xTask ); + +/* + * We prepare an unconstrained task (possibly NULL) + * and then call `uxTaskGetTaskNumber` + */ +void harness() +{ + TaskHandle_t xTask; + UBaseType_t uxTaskNumber; + + vPrepareTask( &xTask ); + + uxTaskNumber = uxTaskGetTaskNumber( xTask ); +} diff --git a/FreeRTOS/Test/CBMC/proofs/Task/TaskGetTaskNumber/tasks_test_access_functions.h b/FreeRTOS/Test/CBMC/proofs/Task/TaskGetTaskNumber/tasks_test_access_functions.h new file mode 100644 index 000000000..cfd998f3a --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Task/TaskGetTaskNumber/tasks_test_access_functions.h @@ -0,0 +1,53 @@ +/* + * FreeRTOS memory safety proofs with CBMC. + * Copyright (C) 2019 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 "cbmc.h" + +/* + * We allocate a TCB and set some members to basic values + */ +TaskHandle_t xUnconstrainedTCB( void ) +{ + TCB_t * pxTCB = pvPortMalloc(sizeof(TCB_t)); + + if ( pxTCB == NULL ) + return NULL; + + return pxTCB; +} + +/* + * We try to allocate an unconstrained TCB but do not + * check for NULL errors here (the function does it) + */ +void vPrepareTask( TaskHandle_t * xTask ) +{ + __CPROVER_assert_zero_allocation(); + + *xTask = xUnconstrainedTCB(); +} diff --git a/FreeRTOS/Test/CBMC/proofs/Task/TaskGetTickCount/Makefile.json b/FreeRTOS/Test/CBMC/proofs/Task/TaskGetTickCount/Makefile.json new file mode 100644 index 000000000..e9da10fef --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Task/TaskGetTickCount/Makefile.json @@ -0,0 +1,40 @@ +# +# FreeRTOS memory safety proofs with CBMC. +# Copyright (C) 2019 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": "TaskGetTickCount", + "CBMCFLAGS": + [ + "--unwind 1" + ], + "OBJS": + [ + "$(ENTRY)_harness.goto", + "$(FREERTOS)/Source/tasks.goto" + ] +} diff --git a/FreeRTOS/Test/CBMC/proofs/Task/TaskGetTickCount/README.md b/FreeRTOS/Test/CBMC/proofs/Task/TaskGetTickCount/README.md new file mode 100644 index 000000000..dea602356 --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Task/TaskGetTickCount/README.md @@ -0,0 +1,5 @@ +This proof demonstrates the memory safety of the TaskIncrementTick function. +No assumptions nor abstractions are required for single-threaded computation. + +This proof is a work-in-progress. Proof assumptions are described in +the harness. diff --git a/FreeRTOS/Test/CBMC/proofs/Task/TaskGetTickCount/TaskGetTickCount_harness.c b/FreeRTOS/Test/CBMC/proofs/Task/TaskGetTickCount/TaskGetTickCount_harness.c new file mode 100644 index 000000000..4229606eb --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Task/TaskGetTickCount/TaskGetTickCount_harness.c @@ -0,0 +1,40 @@ +/* + * FreeRTOS memory safety proofs with CBMC. + * Copyright (C) 2019 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" + +void harness() +{ + TickType_t xTickCount; + + xTickCount = xTaskGetTickCount(); +} diff --git a/FreeRTOS/Test/CBMC/proofs/Task/TaskIncrementTick/Configurations.json b/FreeRTOS/Test/CBMC/proofs/Task/TaskIncrementTick/Configurations.json new file mode 100644 index 000000000..12cc4e7b4 --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Task/TaskIncrementTick/Configurations.json @@ -0,0 +1,63 @@ +# +# FreeRTOS memory safety proofs with CBMC. +# Copyright (C) 2019 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": "TaskIncrementTick", + "DEF": + [ + { "default": + [ + "FREERTOS_MODULE_TEST", + "'mtCOVERAGE_TEST_MARKER()=__CPROVER_assert(1, \"Coverage marker\")'", + "configUSE_TICK_HOOK=0" + ] + }, + { "useTickHook1": + [ + "FREERTOS_MODULE_TEST", + "'mtCOVERAGE_TEST_MARKER()=__CPROVER_assert(1, \"Coverage marker\")'", + "configUSE_TICK_HOOK=1" + ] + } + ], + "CBMCFLAGS": + [ + "--unwind 1", + "--unwindset prvInitialiseTaskLists.0:8,vListInsert.0:2,xTaskIncrementTick.0:4" + ], + "OBJS": + [ + "$(ENTRY)_harness.goto", + "$(FREERTOS)/Source/tasks.goto", + "$(FREERTOS)/Source/list.goto" + ], + "INC": + [ + "$(FREERTOS)/Test/CBMC/proofs/Task/TaskIncrementTick/" + ] +} diff --git a/FreeRTOS/Test/CBMC/proofs/Task/TaskIncrementTick/README.md b/FreeRTOS/Test/CBMC/proofs/Task/TaskIncrementTick/README.md new file mode 100644 index 000000000..84f0fea11 --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Task/TaskIncrementTick/README.md @@ -0,0 +1,18 @@ +This proof demonstrates the memory safety of the TaskIncrementTick function. +We assume that task lists are initialized and filled with a few list items. We +also assign nondeterministic values to some global variables. + +Configurations available: + * `default`: The default configuration. `useTickHook1`: The default + * configuration with `configUSE_TICK_HOOK=1` + +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: + +* prvTraceGetTaskNumber +* prvTracePortGetTimeStamp +* prvTraceStoreKernelCallWithNumericParamOnly +* prvTraceStoreTaskReady +* vApplicationTickHook diff --git a/FreeRTOS/Test/CBMC/proofs/Task/TaskIncrementTick/TaskIncrementTick_harness.c b/FreeRTOS/Test/CBMC/proofs/Task/TaskIncrementTick/TaskIncrementTick_harness.c new file mode 100644 index 000000000..db2b41472 --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Task/TaskIncrementTick/TaskIncrementTick_harness.c @@ -0,0 +1,53 @@ +/* + * FreeRTOS memory safety proofs with CBMC. + * Copyright (C) 2019 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" + +void vSetGlobalVariables(); +BaseType_t xPrepareTaskLists( void ); + +/* + * The harness test first calls two functions included in the tasks.c file + * that initialize the task lists and other global variables + */ +void harness() +{ + BaseType_t xTasksPrepared; + + vSetGlobalVariables(); + xTasksPrepared = xPrepareTaskLists(); + + if ( xTasksPrepared != pdFAIL ) + { + xTaskIncrementTick(); + } +} diff --git a/FreeRTOS/Test/CBMC/proofs/Task/TaskIncrementTick/tasks_test_access_functions.h b/FreeRTOS/Test/CBMC/proofs/Task/TaskIncrementTick/tasks_test_access_functions.h new file mode 100644 index 000000000..e6bf00058 --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Task/TaskIncrementTick/tasks_test_access_functions.h @@ -0,0 +1,126 @@ +/* + * FreeRTOS memory safety proofs with CBMC. + * Copyright (C) 2019 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 "cbmc.h" + +/* + * We allocate a TCB and set some members to basic values + */ +TaskHandle_t xUnconstrainedTCB( void ) +{ + TCB_t * pxTCB = pvPortMalloc(sizeof(TCB_t)); + + if ( pxTCB == NULL ) + return NULL; + + __CPROVER_assume( pxTCB->uxPriority < configMAX_PRIORITIES ); + + vListInitialiseItem( &( pxTCB->xStateListItem ) ); + vListInitialiseItem( &( pxTCB->xEventListItem ) ); + + listSET_LIST_ITEM_OWNER( &( pxTCB->xStateListItem ), pxTCB ); + listSET_LIST_ITEM_OWNER( &( pxTCB->xEventListItem ), pxTCB ); + + if ( nondet_bool() ) + { + listSET_LIST_ITEM_VALUE( &( pxTCB->xStateListItem ), pxTCB->uxPriority ); + } + else + { + listSET_LIST_ITEM_VALUE( &( pxTCB->xStateListItem ), portMAX_DELAY ); + } + + if ( nondet_bool() ) + { + listSET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ), ( TickType_t ) configMAX_PRIORITIES - ( TickType_t ) pxTCB->uxPriority ); + } + else + { + listSET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ), portMAX_DELAY ); + } + return pxTCB; +} + +/* + * We set the values of relevant global + * variables to nondeterministic values + */ +void vSetGlobalVariables() +{ + xPendedTicks = nondet_ubasetype(); + uxSchedulerSuspended = nondet_ubasetype(); + xYieldPending = nondet_basetype(); + xTickCount = nondet_ticktype(); +} + +/* + * We initialise and fill the task lists so coverage is optimal. + * This initialization is not guaranteed to be minimal, but it + * is quite efficient and it serves the same purpose + */ +BaseType_t xPrepareTaskLists( void ) +{ + TCB_t * pxTCB = NULL; + + __CPROVER_assert_zero_allocation(); + + prvInitialiseTaskLists(); + + /* Needed for coverage: This task will be moved to a ready list */ + pxTCB = xUnconstrainedTCB(); + if ( pxTCB == NULL ) + { + return pdFAIL; + } + vListInsert( pxOverflowDelayedTaskList, &( pxTCB->xStateListItem ) ); + + /* Needed for coverage. */ + listGET_OWNER_OF_NEXT_ENTRY( pxTCB , pxOverflowDelayedTaskList ); + + pxTCB = xUnconstrainedTCB(); + if ( pxTCB == NULL ) + { + return pdFAIL; + } + vListInsert( &xPendingReadyList, &( pxTCB->xStateListItem ) ); + + /* Needed for coverage: A nondeterministic choice */ + if ( nondet_bool() ) + { + vListInsert( pxOverflowDelayedTaskList, &( pxTCB->xEventListItem ) ); + } + + pxCurrentTCB = xUnconstrainedTCB(); + if ( pxCurrentTCB == NULL ) + { + return pdFAIL; + } + vListInsert( &pxReadyTasksLists[ pxCurrentTCB->uxPriority ], &( pxCurrentTCB->xStateListItem ) ); + + return pdPASS; +} diff --git a/FreeRTOS/Test/CBMC/proofs/Task/TaskPrioritySet/Makefile.json b/FreeRTOS/Test/CBMC/proofs/Task/TaskPrioritySet/Makefile.json new file mode 100644 index 000000000..9502f830f --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Task/TaskPrioritySet/Makefile.json @@ -0,0 +1,54 @@ +# +# FreeRTOS memory safety proofs with CBMC. +# Copyright (C) 2019 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": "TaskPrioritySet", + "DEF": + [ + "FREERTOS_MODULE_TEST", + "'mtCOVERAGE_TEST_MARKER()=__CPROVER_assert(1, \"Coverage marker\")'", + "configUSE_TRACE_FACILITY=0", + "configGENERATE_RUN_TIME_STATS=0" + ], + "CBMCFLAGS": + [ + "--unwind 1", + "--unwindset prvInitialiseTaskLists.0:8,vListInsert.0:3" + + ], + "OBJS": + [ + "$(ENTRY)_harness.goto", + "$(FREERTOS)/Source/tasks.goto", + "$(FREERTOS)/Source/list.goto" + ], + "INC": + [ + "$(FREERTOS)/Test/CBMC/proofs/Task/TaskPrioritySet/" + ] +} diff --git a/FreeRTOS/Test/CBMC/proofs/Task/TaskPrioritySet/README.md b/FreeRTOS/Test/CBMC/proofs/Task/TaskPrioritySet/README.md new file mode 100644 index 000000000..d9b79a1f4 --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Task/TaskPrioritySet/README.md @@ -0,0 +1,14 @@ +This proof demonstrates the memory safety of the TaskPrioritySet function. The +initialization for the task to be set and `pxCurrentTCB` is quite similar +(since the task handle may be NULL, and in that case `pxCurrentTCB` is used). +Task lists are initialized with these tasks and nondet. filled with a few more +items. + +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 diff --git a/FreeRTOS/Test/CBMC/proofs/Task/TaskPrioritySet/TaskPrioritySet_harness.c b/FreeRTOS/Test/CBMC/proofs/Task/TaskPrioritySet/TaskPrioritySet_harness.c new file mode 100644 index 000000000..30339538d --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Task/TaskPrioritySet/TaskPrioritySet_harness.c @@ -0,0 +1,57 @@ +/* + * FreeRTOS memory safety proofs with CBMC. + * Copyright (C) 2019 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" + +BaseType_t xPrepareTaskLists( TaskHandle_t * xTask ); + +/* + * We assume `uxNewPriority` to be a valid priority (avoids failed assert). + * The harness test first calls two functions included in the tasks.c file + * that initialize the task lists and other global variables + */ +void harness() +{ + TaskHandle_t xTask; + UBaseType_t uxNewPriority; + BaseType_t xTasksPrepared; + + __CPROVER_assume( uxNewPriority < configMAX_PRIORITIES ); + + xTasksPrepared = xPrepareTaskLists( &xTask ); + + /* Check that this second invocation of xPrepareTaskLists is needed. */ + if ( xPrepareTaskLists( &xTask ) != pdFAIL ) + { + vTaskPrioritySet( xTask, uxNewPriority ); + } +} diff --git a/FreeRTOS/Test/CBMC/proofs/Task/TaskPrioritySet/tasks_test_access_functions.h b/FreeRTOS/Test/CBMC/proofs/Task/TaskPrioritySet/tasks_test_access_functions.h new file mode 100644 index 000000000..9128138ab --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Task/TaskPrioritySet/tasks_test_access_functions.h @@ -0,0 +1,125 @@ +/* + * FreeRTOS memory safety proofs with CBMC. + * Copyright (C) 2019 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 "cbmc.h" + +/* + * We allocate a TCB and set some members to basic values + */ +TaskHandle_t xUnconstrainedTCB( void ) +{ + TCB_t * pxTCB = pvPortMalloc(sizeof(TCB_t)); + uint8_t ucStaticAllocationFlag; + + if ( pxTCB == NULL ) + return NULL; + + __CPROVER_assume( pxTCB->uxPriority < configMAX_PRIORITIES ); + + vListInitialiseItem( &( pxTCB->xStateListItem ) ); + vListInitialiseItem( &( pxTCB->xEventListItem ) ); + + listSET_LIST_ITEM_OWNER( &( pxTCB->xStateListItem ), pxTCB ); + listSET_LIST_ITEM_OWNER( &( pxTCB->xEventListItem ), pxTCB ); + + if ( nondet_bool() ) + { + listSET_LIST_ITEM_VALUE( &( pxTCB->xStateListItem ), pxTCB->uxPriority ); + } + else + { + listSET_LIST_ITEM_VALUE( &( pxTCB->xStateListItem ), portMAX_DELAY ); + } + + if ( nondet_bool() ) + { + listSET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ), ( TickType_t ) configMAX_PRIORITIES - ( TickType_t ) pxTCB->uxPriority ); + } + else + { + listSET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ), portMAX_DELAY ); + } + + return pxTCB; +} + +/* + * We initialise and fill the task lists so coverage is optimal. + * This initialization is not guaranteed to be minimal, but it + * is quite efficient and it serves the same purpose + */ +BaseType_t xPrepareTaskLists( TaskHandle_t * xTask ) +{ + TCB_t * pxTCB = NULL; + + __CPROVER_assert_zero_allocation(); + + prvInitialiseTaskLists(); + + pxTCB = xUnconstrainedTCB(); + + /* Needed for coverage: nondet insertion of task. */ + if ( nondet_bool() ) + { + TCB_t * pxOtherTCB; + pxOtherTCB = xUnconstrainedTCB(); + if ( pxOtherTCB != NULL ) + { + vListInsert( &pxReadyTasksLists[ pxOtherTCB->uxPriority ], &( pxOtherTCB->xStateListItem ) ); + } + } + + if ( pxTCB != NULL ) + { + /* Needed for coverage: nondeterministic insertion of task */ + if ( nondet_bool() ) + { + vListInsert( &pxReadyTasksLists[ pxTCB->uxPriority ], &( pxTCB->xStateListItem ) ); + } + } + + /* Note that `*xTask = NULL` can happen here, but this is fine -- `pxCurrentTCB` will be used instead */ + *xTask = pxTCB; + + pxCurrentTCB = xUnconstrainedTCB(); + if ( pxCurrentTCB == NULL ) + { + return pdFAIL; + } + + /* Needed for coverage: nondeterministic insertion of task */ + if ( nondet_bool() ) + { + vListInsert( &pxReadyTasksLists[ pxCurrentTCB->uxPriority ], &( pxCurrentTCB->xStateListItem ) ); + + /* Needed for coverage. */ + listGET_OWNER_OF_NEXT_ENTRY( pxCurrentTCB , &pxReadyTasksLists[ pxCurrentTCB->uxPriority ] ); + } + + return pdPASS; +} diff --git a/FreeRTOS/Test/CBMC/proofs/Task/TaskResumeAll/Configurations.json b/FreeRTOS/Test/CBMC/proofs/Task/TaskResumeAll/Configurations.json new file mode 100644 index 000000000..d2d1ab1f3 --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Task/TaskResumeAll/Configurations.json @@ -0,0 +1,69 @@ +# +# FreeRTOS memory safety proofs with CBMC. +# Copyright (C) 2019 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": "TaskResumeAll", + "DEF": + [ + { "default": + [ + "FREERTOS_MODULE_TEST", + "PENDED_TICKS=1", + "'mtCOVERAGE_TEST_MARKER()=__CPROVER_assert(1, \"Coverage marker\")'", + "configUSE_TRACE_FACILITY=0", + "configGENERATE_RUN_TIME_STATS=0" + ] + }, + { "useTickHook1": + [ + "FREERTOS_MODULE_TEST", + "PENDED_TICKS=1", + "'mtCOVERAGE_TEST_MARKER()=__CPROVER_assert(1, \"Coverage marker\")'", + "configUSE_TRACE_FACILITY=0", + "configGENERATE_RUN_TIME_STATS=0", + "configUSE_TICK_HOOK=1" + ] + } + ], + "CBMCFLAGS": + [ + "--unwind 1", + "--unwindset prvInitialiseTaskLists.0:8,xTaskResumeAll.0:2,vListInsert.0:5,xTaskIncrementTick.0:4" + + ], + "OBJS": + [ + "$(ENTRY)_harness.goto", + "$(FREERTOS)/Source/tasks.goto", + "$(FREERTOS)/Source/list.goto" + ], + "INC": + [ + "$(FREERTOS)/Test/CBMC/proofs/Task/TaskResumeAll/" + ] +} diff --git a/FreeRTOS/Test/CBMC/proofs/Task/TaskResumeAll/README.md b/FreeRTOS/Test/CBMC/proofs/Task/TaskResumeAll/README.md new file mode 100644 index 000000000..e4e0e17ae --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Task/TaskResumeAll/README.md @@ -0,0 +1,19 @@ +This proof demonstrates the memory safety of the TaskResumeAll function. We +assume that task lists are initialized and filled with a few list items. We +also assume that some global variables are set to a nondeterministic value, +except for `uxSchedulerSuspended` which cannot be 0 and `xPendedTicks` which +is either `1` (to unwind a loop in a reasonable amount of time) or `0`. + +Configurations available: + * `default`: The default configuration. + * `useTickHook1`: The default configuration with `configUSE_TICK_HOOK=1` + +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: + +* vApplicationTickHook +* vPortEnterCritical +* vPortExitCritical +* vPortGenerateSimulatedInterrupt diff --git a/FreeRTOS/Test/CBMC/proofs/Task/TaskResumeAll/TaskResumeAll_harness.c b/FreeRTOS/Test/CBMC/proofs/Task/TaskResumeAll/TaskResumeAll_harness.c new file mode 100644 index 000000000..fbb4956f5 --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Task/TaskResumeAll/TaskResumeAll_harness.c @@ -0,0 +1,53 @@ +/* + * FreeRTOS memory safety proofs with CBMC. + * Copyright (C) 2019 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" + +void vSetGlobalVariables( void ); +BaseType_t xPrepareTaskLists( void ); + +/* + * The harness test first calls two functions included in the tasks.c file + * that initialize the task lists and other global variables + */ +void harness() +{ + BaseType_t xTasksPrepared; + + vSetGlobalVariables(); + xTasksPrepared = xPrepareTaskLists(); + + if ( xTasksPrepared != pdFAIL ) + { + xTaskResumeAll(); + } +} diff --git a/FreeRTOS/Test/CBMC/proofs/Task/TaskResumeAll/tasks_test_access_functions.h b/FreeRTOS/Test/CBMC/proofs/Task/TaskResumeAll/tasks_test_access_functions.h new file mode 100644 index 000000000..981cd8284 --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Task/TaskResumeAll/tasks_test_access_functions.h @@ -0,0 +1,138 @@ +/* + * FreeRTOS memory safety proofs with CBMC. + * Copyright (C) 2019 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 "cbmc.h" + +/* + * We allocate a TCB and set some members to basic values + */ +TaskHandle_t xUnconstrainedTCB( void ) +{ + TCB_t * pxTCB = pvPortMalloc(sizeof(TCB_t)); + + if ( pxTCB == NULL ) + return NULL; + + __CPROVER_assume( pxTCB->uxPriority < configMAX_PRIORITIES ); + + vListInitialiseItem( &( pxTCB->xStateListItem ) ); + vListInitialiseItem( &( pxTCB->xEventListItem ) ); + + listSET_LIST_ITEM_OWNER( &( pxTCB->xStateListItem ), pxTCB ); + listSET_LIST_ITEM_OWNER( &( pxTCB->xEventListItem ), pxTCB ); + + if ( nondet_bool() ) + { + listSET_LIST_ITEM_VALUE( &( pxTCB->xStateListItem ), pxTCB->uxPriority ); + } + else + { + listSET_LIST_ITEM_VALUE( &( pxTCB->xStateListItem ), portMAX_DELAY ); + } + + if ( nondet_bool() ) + { + listSET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ), ( TickType_t ) configMAX_PRIORITIES - ( TickType_t ) pxTCB->uxPriority ); + } + else + { + listSET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ), portMAX_DELAY ); + } + return pxTCB; +} + +/* + * We set xPendedTicks since __CPROVER_assume does not work + * well with statically initialised variables + */ +void vSetGlobalVariables( void ) { + UBaseType_t uxNonZeroValue; + + __CPROVER_assume( uxNonZeroValue != 0 ); + + uxSchedulerSuspended = uxNonZeroValue; + xPendedTicks = nondet_bool() ? PENDED_TICKS : 0; + uxCurrentNumberOfTasks = nondet_ubasetype(); + xTickCount = nondet_ticktype(); +} + +/* + * We initialise and fill the task lists so coverage is optimal. + * This initialization is not guaranteed to be minimal, but it + * is quite efficient and it serves the same purpose + */ +BaseType_t xPrepareTaskLists( void ) +{ + TCB_t * pxTCB = NULL; + + __CPROVER_assert_zero_allocation(); + + prvInitialiseTaskLists(); + + /* This task will be moved to a ready list, granting coverage + * on lines 2780-2786 (tasks.c) */ + pxTCB = xUnconstrainedTCB(); + if ( pxTCB == NULL ) + { + return pdFAIL; + } + vListInsert( pxOverflowDelayedTaskList, &( pxTCB->xStateListItem ) ); + + /* Use of this macro ensures coverage on line 185 (list.c) */ + listGET_OWNER_OF_NEXT_ENTRY( pxTCB , pxOverflowDelayedTaskList ); + + pxTCB = xUnconstrainedTCB(); + if ( pxTCB == NULL ) + { + return pdFAIL; + } + vListInsert( &xPendingReadyList, &( pxTCB->xStateListItem ) ); + vListInsert( pxOverflowDelayedTaskList, &( pxTCB->xEventListItem ) ); + + pxTCB = xUnconstrainedTCB(); + if ( pxTCB == NULL ) + { + return pdFAIL; + } + vListInsert( pxOverflowDelayedTaskList, &( pxTCB->xStateListItem ) ); + + /* This nondeterministic choice ensure coverage in line 2746 (tasks.c) */ + if ( nondet_bool() ) + { + vListInsert( pxOverflowDelayedTaskList, &( pxTCB->xEventListItem ) ); + } + + pxCurrentTCB = xUnconstrainedTCB(); + if ( pxCurrentTCB == NULL ) + { + return pdFAIL; + } + vListInsert( &pxReadyTasksLists[ pxCurrentTCB->uxPriority ], &( pxCurrentTCB->xStateListItem ) ); + + return pdPASS; +} diff --git a/FreeRTOS/Test/CBMC/proofs/Task/TaskSetTimeOutState/Makefile.json b/FreeRTOS/Test/CBMC/proofs/Task/TaskSetTimeOutState/Makefile.json new file mode 100644 index 000000000..86e5e4b02 --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Task/TaskSetTimeOutState/Makefile.json @@ -0,0 +1,48 @@ +# +# FreeRTOS memory safety proofs with CBMC. +# Copyright (C) 2019 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": "TaskSetTimeOutState", + "DEF": + [ + "'mtCOVERAGE_TEST_MARKER()=__CPROVER_assert(1, \"Coverage marker\")'" + ], + "CBMCFLAGS": + [ + "--unwind 1" + ], + "OBJS": + [ + "$(ENTRY)_harness.goto", + "$(FREERTOS)/Source/tasks.goto" + ], + "INC": + [ + "$(FREERTOS)/Test/CBMC/proofs/Task/TaskSetTimeOutState/" + ] +} diff --git a/FreeRTOS/Test/CBMC/proofs/Task/TaskSetTimeOutState/README.md b/FreeRTOS/Test/CBMC/proofs/Task/TaskSetTimeOutState/README.md new file mode 100644 index 000000000..c4d1ecfa9 --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Task/TaskSetTimeOutState/README.md @@ -0,0 +1,10 @@ +This proof demonstrates the memory safety of the TaskSetTimeOutState function. +No assumption is required other than its single argument being non-NULL. + +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 diff --git a/FreeRTOS/Test/CBMC/proofs/Task/TaskSetTimeOutState/TaskSetTimeOutState_harness.c b/FreeRTOS/Test/CBMC/proofs/Task/TaskSetTimeOutState/TaskSetTimeOutState_harness.c new file mode 100644 index 000000000..b38aee6ea --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Task/TaskSetTimeOutState/TaskSetTimeOutState_harness.c @@ -0,0 +1,44 @@ +/* + * FreeRTOS memory safety proofs with CBMC. + * Copyright (C) 2019 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" + +/* + * We assume xTime to allocated since the function includes a configASSERT + * call at the beginning to make sure the pointer to it is not NULL + */ +void harness() +{ + TimeOut_t xTime; + + vTaskSetTimeOutState( &xTime ); +} diff --git a/FreeRTOS/Test/CBMC/proofs/Task/TaskStartScheduler/Makefile.json b/FreeRTOS/Test/CBMC/proofs/Task/TaskStartScheduler/Makefile.json new file mode 100644 index 000000000..e2b8610ef --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Task/TaskStartScheduler/Makefile.json @@ -0,0 +1,55 @@ +# +# FreeRTOS memory safety proofs with CBMC. +# Copyright (C) 2019 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": "TaskStartScheduler", + "DEF": + [ + "FREERTOS_MODULE_TEST", + "'mtCOVERAGE_TEST_MARKER()=__CPROVER_assert(1, \"Coverage marker\")'", + "configUSE_TRACE_FACILITY=0", + "configGENERATE_RUN_TIME_STATS=0" + ], + "CBMCFLAGS": + [ + "--unwind 1", + "--unwindset prvInitialiseTaskLists.0:8,prvInitialiseNewTask.0:16,prvInitialiseNewTask.1:4" + ], + "OBJS": + [ + "$(ENTRY)_harness.goto", + "$(FREERTOS)/Source/tasks.goto", + "$(FREERTOS)/Source/list.goto", + "$(FREERTOS)/Source/timers.goto", + "$(FREERTOS)/Source/queue.goto" + ], + "INC": + [ + "$(FREERTOS)/Test/CBMC/proofs/Task/TaskStartScheduler/" + ] +} diff --git a/FreeRTOS/Test/CBMC/proofs/Task/TaskStartScheduler/README.md b/FreeRTOS/Test/CBMC/proofs/Task/TaskStartScheduler/README.md new file mode 100644 index 000000000..4e0294f7c --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Task/TaskStartScheduler/README.md @@ -0,0 +1,18 @@ +This proof demonstrates the memory safety of the TaskStartScheduler function. +We assume that buffers for `pxIdleTaskTCB` and `pxTimerTaskTCB` (and their +associated stacks `pxIdleTaskStack` and `pxTimerTaskStack`) have been +previously allocated. The arguments passed by reference to +`vApplicationGetIdleTaskMemory` and `vApplicationGetTimerTaskMemory` are +assigned to these pointers since both functions expect statically-allocated +buffers to be passed. + +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: + +* pxPortInitialiseStack +* vConfigureTimerForRunTimeStats +* vPortEnterCritical +* vPortExitCritical +* xPortStartScheduler diff --git a/FreeRTOS/Test/CBMC/proofs/Task/TaskStartScheduler/TaskStartScheduler_harness.c b/FreeRTOS/Test/CBMC/proofs/Task/TaskStartScheduler/TaskStartScheduler_harness.c new file mode 100644 index 000000000..ffa84fab1 --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Task/TaskStartScheduler/TaskStartScheduler_harness.c @@ -0,0 +1,51 @@ +/* + * FreeRTOS memory safety proofs with CBMC. + * Copyright (C) 2019 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" + +BaseType_t xPrepareTasks( void ); + +/* + * We prepare `pxCurrentTCB` and the idle/timer task buffers + * (TCB + stack), then we call the function if allocation was ok + */ +void harness() +{ + BaseType_t xTasksPrepared; + + xTasksPrepared = xPrepareTasks(); + + if ( xTasksPrepared != pdFAIL ) + { + vTaskStartScheduler(); + } +} diff --git a/FreeRTOS/Test/CBMC/proofs/Task/TaskStartScheduler/tasks_test_access_functions.h b/FreeRTOS/Test/CBMC/proofs/Task/TaskStartScheduler/tasks_test_access_functions.h new file mode 100644 index 000000000..e985b51bc --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Task/TaskStartScheduler/tasks_test_access_functions.h @@ -0,0 +1,110 @@ +/* + * FreeRTOS memory safety proofs with CBMC. + * Copyright (C) 2019 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 "cbmc.h" + +/* + * We allocate an unconstrained TCB or return NULL if it fails + */ +TaskHandle_t xUnconstrainedTCB( void ) +{ + TCB_t * pxTCB = pvPortMalloc(sizeof(TCB_t)); + + if ( pxTCB == NULL ) + return NULL; + + return pxTCB; +} + +StaticTask_t *pxIdleTaskTCB; +StaticTask_t *pxTimerTaskTCB; +StackType_t *pxIdleTaskStack; +StackType_t *pxTimerTaskStack; + +/* + * `pxCurrentTCB` allocation is allowed to fail. The global variables above + * this comment are used in the stubbed functions `vApplicationGetIdleTaskMemory` + * and `vApplicationGetTimerTaskMemory` (at the end of this file) and buffer allocation + * must be succesful for the proof to have no errors + */ +BaseType_t xPrepareTasks( void ) +{ + __CPROVER_assert_zero_allocation(); + + prvInitialiseTaskLists(); + + pxCurrentTCB = xUnconstrainedTCB(); + + pxIdleTaskTCB = pvPortMalloc(sizeof(StaticTask_t)); + if (pxIdleTaskTCB == NULL ) + { + return pdFAIL; + } + + pxIdleTaskStack = pvPortMalloc( sizeof(StackType_t) * configMINIMAL_STACK_SIZE ); + if ( pxIdleTaskStack == NULL ) + { + return pdFAIL; + } + + pxTimerTaskTCB = pvPortMalloc( sizeof(StaticTask_t) ); + if ( pxTimerTaskTCB == NULL ) + { + return pdFAIL; + } + + pxTimerTaskStack = pvPortMalloc( sizeof(StackType_t) * configTIMER_TASK_STACK_DEPTH ); + if ( pxTimerTaskStack == NULL ) + { + return pdFAIL; + } + + return pdPASS; +} + +/* + * The buffers used here have been succesfully allocated before (global variables) + */ +void vApplicationGetIdleTaskMemory( StaticTask_t ** ppxIdleTaskTCBBuffer, + StackType_t ** ppxIdleTaskStackBuffer, + uint32_t * pulIdleTaskStackSize ) +{ + *ppxIdleTaskTCBBuffer = pxIdleTaskTCB; + *ppxIdleTaskStackBuffer = pxIdleTaskStack; + *pulIdleTaskStackSize = configMINIMAL_STACK_SIZE; +} + +/* + * The buffers used here have been succesfully allocated before (global variables) + */ +void vApplicationGetTimerTaskMemory( StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint32_t *pulTimerTaskStackSize ) +{ + *ppxTimerTaskTCBBuffer = pxTimerTaskTCB; + *ppxTimerTaskStackBuffer = pxTimerTaskStack; + *pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH; +} diff --git a/FreeRTOS/Test/CBMC/proofs/Task/TaskSuspendAll/Makefile.json b/FreeRTOS/Test/CBMC/proofs/Task/TaskSuspendAll/Makefile.json new file mode 100644 index 000000000..e9403c769 --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Task/TaskSuspendAll/Makefile.json @@ -0,0 +1,49 @@ +# +# FreeRTOS memory safety proofs with CBMC. +# Copyright (C) 2019 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": "TaskSuspendAll", + "DEF": + [ + "'mtCOVERAGE_TEST_MARKER()=__CPROVER_assert(1, \"Coverage marker\")'" + ], + "CBMCFLAGS": + [ + "--unwind 1" + ], + "OBJS": + [ + "$(ENTRY)_harness.goto", + "$(FREERTOS)/Source/tasks.goto", + "$(FREERTOS)/Source/list.goto" + ], + "INC": + [ + "$(FREERTOS)/Test/CBMC/proofs/Task/TaskSuspendAll/" + ] +} diff --git a/FreeRTOS/Test/CBMC/proofs/Task/TaskSuspendAll/README.md b/FreeRTOS/Test/CBMC/proofs/Task/TaskSuspendAll/README.md new file mode 100644 index 000000000..3aa4e5e93 --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Task/TaskSuspendAll/README.md @@ -0,0 +1,5 @@ +This proof demonstrates the memory safety of the TaskSuspendAll function. +No assumption or abstraction is required for this memory-safety proof. + +This proof is a work-in-progress. Proof assumptions are described in +the harness. diff --git a/FreeRTOS/Test/CBMC/proofs/Task/TaskSuspendAll/TaskSuspendAll_harness.c b/FreeRTOS/Test/CBMC/proofs/Task/TaskSuspendAll/TaskSuspendAll_harness.c new file mode 100644 index 000000000..3fe438229 --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Task/TaskSuspendAll/TaskSuspendAll_harness.c @@ -0,0 +1,42 @@ +/* + * FreeRTOS memory safety proofs with CBMC. + * Copyright (C) 2019 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" + +/* + * We just call vTaskSuspendAll(). No assumption + * or abstraction is required for this proof + */ +void harness() +{ + vTaskSuspendAll(); +} diff --git a/FreeRTOS/Test/CBMC/proofs/Task/TaskSwitchContext/Makefile.json b/FreeRTOS/Test/CBMC/proofs/Task/TaskSwitchContext/Makefile.json new file mode 100644 index 000000000..a17a721ca --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Task/TaskSwitchContext/Makefile.json @@ -0,0 +1,52 @@ +# +# FreeRTOS memory safety proofs with CBMC. +# Copyright (C) 2019 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": "TaskSwitchContext", + "DEF": + [ + "FREERTOS_MODULE_TEST", + "'portGET_HIGHEST_PRIORITY(uxTopPriority, uxReadyPriorities)=__CPROVER_assume( uxTopPriority < configMAX_PRIORITIES )'", + "'mtCOVERAGE_TEST_MARKER()=__CPROVER_assert(1, \"Coverage marker\")'" + ], + "CBMCFLAGS": + [ + "--unwind 1", + "--unwindset prvInitialiseTaskLists.0:8,xPrepareTaskLists.0:8,vListInsert.0:2" + ], + "OBJS": + [ + "$(ENTRY)_harness.goto", + "$(FREERTOS)/Source/tasks.goto", + "$(FREERTOS)/Source/list.goto" + ], + "INC": + [ + "$(FREERTOS)/Test/CBMC/proofs/Task/TaskSwitchContext/" + ] +} diff --git a/FreeRTOS/Test/CBMC/proofs/Task/TaskSwitchContext/README.md b/FreeRTOS/Test/CBMC/proofs/Task/TaskSwitchContext/README.md new file mode 100644 index 000000000..5bc20c5e5 --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Task/TaskSwitchContext/README.md @@ -0,0 +1,14 @@ +This proof demonstrates the memory safety of the TaskSwitchContext function. +We assume task ready lists to be initialized and filled with one element each, +and `pxCurrentTCB` to be the highest priority task. We also set +`uxSchedulerSuspended` to a nondeterministic value. + +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: + +* prvTraceGetCurrentTaskHandle +* prvTraceGetTaskNumber +* prvTraceStoreTaskswitch +* ulGetRunTimeCounterValue diff --git a/FreeRTOS/Test/CBMC/proofs/Task/TaskSwitchContext/TaskSwitchContext_harness.c b/FreeRTOS/Test/CBMC/proofs/Task/TaskSwitchContext/TaskSwitchContext_harness.c new file mode 100644 index 000000000..52295bc81 --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Task/TaskSwitchContext/TaskSwitchContext_harness.c @@ -0,0 +1,54 @@ +/* + * FreeRTOS memory safety proofs with CBMC. + * Copyright (C) 2019 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" + +void vSetGlobalVariables( void ); +BaseType_t xPrepareTaskLists( void ); + +/* + * We prepare task lists by inserting one item in each list, + * and with the macro redefinition we ensure only valid ready + * task lists are checked in `taskSELECT_HIGHEST_PRIORITY_TASK()` + */ +void harness() +{ + BaseType_t xTasksPrepared; + + vSetGlobalVariables(); + xTasksPrepared = xPrepareTaskLists(); + + if ( xTasksPrepared != pdFAIL ) + { + vTaskSwitchContext(); + } +} diff --git a/FreeRTOS/Test/CBMC/proofs/Task/TaskSwitchContext/tasks_test_access_functions.h b/FreeRTOS/Test/CBMC/proofs/Task/TaskSwitchContext/tasks_test_access_functions.h new file mode 100644 index 000000000..2b5ebff7f --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/Task/TaskSwitchContext/tasks_test_access_functions.h @@ -0,0 +1,103 @@ +/* + * FreeRTOS memory safety proofs with CBMC. + * Copyright (C) 2019 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 "cbmc.h" + +/* + * We allocate a TCB and set some members to basic values + */ +TaskHandle_t xUnconstrainedTCB( UBaseType_t uxPriority ) +{ + TCB_t * pxTCB = pvPortMalloc(sizeof(TCB_t)); + + if ( pxTCB == NULL ) + return NULL; + + /* uxPriority is set to a specific priority */ + pxTCB->uxPriority = uxPriority; + + vListInitialiseItem( &( pxTCB->xStateListItem ) ); + vListInitialiseItem( &( pxTCB->xEventListItem ) ); + + listSET_LIST_ITEM_OWNER( &( pxTCB->xStateListItem ), pxTCB ); + listSET_LIST_ITEM_OWNER( &( pxTCB->xEventListItem ), pxTCB ); + + if ( nondet_bool() ) + { + listSET_LIST_ITEM_VALUE( &( pxTCB->xStateListItem ), pxTCB->uxPriority ); + } + else + { + listSET_LIST_ITEM_VALUE( &( pxTCB->xStateListItem ), portMAX_DELAY ); + } + + if ( nondet_bool() ) + { + listSET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ), ( TickType_t ) configMAX_PRIORITIES - ( TickType_t ) pxTCB->uxPriority ); + } + else + { + listSET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ), portMAX_DELAY ); + } + return pxTCB; +} + +/* + * We set the values of relevant global + * variables to nondeterministic values + */ +void vSetGlobalVariables( void ) +{ + uxSchedulerSuspended = nondet_ubasetype(); +} + +/* + * We initialize and fill with one item each ready tasks list + * so that the assertion on line 175 (tasks.c) does not fail + */ +BaseType_t xPrepareTaskLists( void ) +{ + TCB_t * pxTCB = NULL; + + __CPROVER_assert_zero_allocation(); + + prvInitialiseTaskLists(); + + for ( int i = 0; i < configMAX_PRIORITIES; ++i ) + { + pxTCB = xUnconstrainedTCB( i ); + if ( pxTCB == NULL ) + { + return pdFAIL; + } + vListInsert( &pxReadyTasksLists[ pxTCB->uxPriority ], &( pxTCB->xStateListItem ) ); + } + listGET_OWNER_OF_NEXT_ENTRY( pxCurrentTCB, &pxReadyTasksLists[ configMAX_PRIORITIES - 1 ] ); + + return pdPASS; +} diff --git a/FreeRTOS/Test/CBMC/proofs/make_cbmc_batch_files.py b/FreeRTOS/Test/CBMC/proofs/make_cbmc_batch_files.py new file mode 100755 index 000000000..622e000c3 --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/make_cbmc_batch_files.py @@ -0,0 +1,53 @@ +#!/usr/bin/env python3 +# +# Generation of the cbmc-batch.yaml files for the CBMC proofs. +# +# Copyright (C) 2019 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 +import platform +import subprocess + + +def remove_cbmc_yaml_files(): + for dyr, _, files in os.walk("."): + cbmc_batch_files = [os.path.join(os.path.abspath(dyr), file) + for file in files if file == "cbmc-batch.yaml"] + for file in cbmc_batch_files: + os.remove(file) + + +def create_cbmc_yaml_files(): + # The YAML files are only used by CI and are not needed on Windows. + if platform.system() == "Windows": + return + for dyr, _, files in os.walk("."): + harness = [file for file in files if file.endswith("_harness.c")] + if harness and "Makefile" in files: + subprocess.run(["make", "cbmc-batch.yaml"], + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + cwd=os.path.abspath(dyr), + check=True) + +if __name__ == '__main__': + remove_cbmc_yaml_files() + create_cbmc_yaml_files() diff --git a/FreeRTOS/Test/CBMC/proofs/make_common_makefile.py b/FreeRTOS/Test/CBMC/proofs/make_common_makefile.py new file mode 100755 index 000000000..efcf1db8d --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/make_common_makefile.py @@ -0,0 +1,240 @@ +#!/usr/bin/env python3 +# +# Generation of common Makefile for CBMC proofs. +# +# Copyright (C) 2019 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. + +from pprint import pprint +import json +import sys +import re +import os +import argparse + +def cleanup_whitespace(string): + return re.sub('\s+', ' ', string.strip()) + +################################################################ +# Operating system specific values + +platform_definitions = { + "linux": { + "platform": "linux", + "separator": "/", + "define": "-D", + "include": "-I", + }, + "macos": { + "platform": "darwin", + "separator": "/", + "define": "-D", + "include": "-I", + }, + "windows": { + "platform": "win32", + "separator": "\\", + "define": "/D", + "include": "/I", + }, +} + + +def default_platform(): + for platform, definition in platform_definitions.items(): + if sys.platform == definition["platform"]: + return platform + return "linux" + + +def patch_path_separator(opsys, string): + from_separator = '/' + to_separator = platform_definitions[opsys]["separator"] + + def escape_separator(string): + return string.split(from_separator + from_separator) + + def change_separator(string): + return string.replace(from_separator, to_separator) + + return from_separator.join([change_separator(escaped) + for escaped in escape_separator(string)]) + +def patch_compile_output(opsys, line, key, value): + if opsys != "windows": + return line + + if key in ["COMPILE_ONLY", "COMPILE_LINK"] and value is not None: + if value[-1] == '/Fo': + return re.sub('/Fo\s+', '/Fo', line) + if value[-1] == '/Fe': + return re.sub('/Fe\s+', '/Fe', line) + return line + +################################################################ +# Argument parsing +# + +def get_arguments(): + parser = argparse.ArgumentParser() + parser.add_argument( + "--system", + metavar="OS", + choices=platform_definitions, + default=str(default_platform()), + help="Generate makefiles for operating system OS" + ) + return parser.parse_args() + +################################################################ +# Variable definitions +# +# JSON files give variable definitions for common, operating system, +# and harness specfic values +# + +def read_variable_definitions(filename): + variable = {} + with open(filename) as _file: + for key, values in json.load(_file).items(): + variable[cleanup_whitespace(key)] = [cleanup_whitespace(value) + for value in values] + return variable + +def find_definition_once(key, defines, prefix=None): + + # Try looking up key with and without prefix + prefix = "{}_".format(prefix.rstrip('_')) if prefix else "" + key2 = key[len(prefix):] if key.startswith(prefix) else prefix + key + + for _key in [key, key2]: + _value = defines.get(_key) + if _value is not None: + return _value + + return None + +def find_definition(key, defines): + common_defines, opsys_defines, harness_defines = defines + return (find_definition_once(key, harness_defines, "H") or + find_definition_once(key, opsys_defines, "O") or + find_definition_once(key, common_defines, "C")) + +################################################################ +# Makefile generation + +def construct_definition(opsys, key_prefix, value_prefix, key, definitions): + values = definitions.get(key) + if not values: + return "" + if key in ["INC", "DEF"]: + values = [patch_path_separator(opsys, value) + for value in values] + lines = ["\t{}{} \\".format(value_prefix, value) for value in values] + return "{}_{} = \\\n{}\n\t# empty\n".format(key_prefix, + key, + '\n'.join(lines)) + +def write_define(opsys, define, defines, makefile): + value = find_definition(define, defines) + if value: + if define in ["FREERTOS", "PROOFS"]: + value = os.path.abspath(value[0]) + makefile.write("{} = {}\n".format(define, value)) + +def write_common_defines(opsys, defines, makefile): + common_defines, opsys_defines, harness_defines = defines + + for key_prefix, defines in zip(["C", "O", "H"], + [common_defines, + opsys_defines, + harness_defines]): + for value_prefix, key in zip([platform_definitions[opsys]["include"], + platform_definitions[opsys]["define"], + "", ""], + ["INC", "DEF", "OPT", "CBMCFLAGS"]): + define = construct_definition(opsys, + key_prefix, value_prefix, + key, defines) + if define: + makefile.write(define + "\n") + + +def write_makefile(opsys, template, defines, makefile): + with open(template) as _template: + for line in _template: + line = patch_path_separator(opsys, line) + keys = re.findall('@(\w+)@', line) + values = [find_definition(key, defines) for key in keys] + for key, value in zip(keys, values): + if value is not None: + line = line.replace('@{}@'.format(key), " ".join(value)) + line = patch_compile_output(opsys, line, key, value) + makefile.write(line) + +def write_cbmcbatchyaml_target(opsys, _makefile): + target = """ +################################################################ +# Build configuration file to run cbmc under cbmc-batch in CI + +define encode_options +'=$(shell echo $(1) | sed 's/ ,/ /g' | sed 's/ /;/g')=' +endef + +cbmc-batch.yaml: + @echo "Building $@" + @$(RM) $@ + @echo "jobos: ubuntu16" >> $@ + @echo "cbmcflags: $(call encode_options,$(CBMCFLAGS) --unwinding-assertions)" >> $@ + @echo "goto: $(ENTRY).goto" >> $@ + @echo "expected: $(H_EXPECTED)" >> $@ + +################################################################ +""" + if opsys != "windows": + _makefile.write(target) + +def makefile_from_template(opsys, template, defines, makefile="Makefile"): + with open(makefile, "w") as _makefile: + write_define(opsys, "FREERTOS", defines, _makefile) + write_define(opsys, "PROOFS", defines, _makefile) + write_common_defines(opsys, defines, _makefile) + write_makefile(opsys, template, defines, _makefile) + write_cbmcbatchyaml_target(opsys, _makefile) + +################################################################ +# Main + +def main(): + args = get_arguments() + + common_defines = read_variable_definitions("MakefileCommon.json") + opsys_defines = read_variable_definitions("MakefileWindows.json" + if args.system == "windows" + else "MakefileLinux.json") + harness_defines = {} + + makefile_from_template(args.system, + "Makefile.template", + (common_defines, opsys_defines, harness_defines), + "Makefile.common") + +if __name__ == "__main__": + main() diff --git a/FreeRTOS/Test/CBMC/proofs/make_configuration_directories.py b/FreeRTOS/Test/CBMC/proofs/make_configuration_directories.py new file mode 100755 index 000000000..9e006e9ed --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/make_configuration_directories.py @@ -0,0 +1,163 @@ +#!/usr/bin/env python3 +# +# Creating the CBMC proofs from Configurations.json. +# +# Copyright (C) 2019 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 collections +import json +import logging +import os +import pathlib +import shutil +import textwrap + +from make_proof_makefiles import load_json_config_file + +LOGGER = logging.getLogger("ComputeConfigurations") + +def prolog(): + return textwrap.dedent("""\ + This script Generates Makefile.json from Configrations.json. + + Starting in the current directory, it walks down every subdirectory + looking for Configurations.json files. Every found Configurations.json + file is assumed to look similar to the following format: + + { + "ENTRY": "ARPProcessPacket", + "CBMCFLAGS": + [ + "--unwind 1", + "--unwindset vARPRefreshCacheEntry.0:7,memcmp.0:17", + "--nondet-static" + ], + "OBJS": + [ + "$(ENTRY)_harness.goto", + "$(FREERTOS)/lib/FreeRTOS-Plus-TCP/source/FreeRTOS_ARP.goto" + ], + "DEF": + [ + {"disableClashDetection": ["ipconfigARP_USE_CLASH_DETECTION=0"]}, + {"enableClashDetection": ["ipconfigARP_USE_CLASH_DETECTION=1"]} + ] + } + + The format is mainly taken from the Makefile.json files. + The only difference is that it expects a list of json object in the DEF + section. This script will generate a Makefile.json in a subdirectory and + copy the harness to each subdirectory. + The key is later taken as the name for the configuration subdirectory + prexied by 'config_'. + + So for the above script, we get two subdirectories: + -config_disableClashDetection + -config_enableClashDetection + + As an example, the resulting Makefile.json for the + config_disableClashDetection directory will be: + + { + "ENTRY": "ARPProcessPacket", + "CBMCFLAGS": [ + "--unwind 1", + "--unwindset vARPRefreshCacheEntry.0:7,memcmp.0:17", + "--nondet-static" + ], + "OBJS": [ + "$(ENTRY)_harness.goto", + "$(FREERTOS)/lib/FreeRTOS-Plus-TCP/source/FreeRTOS_ARP.goto" + ], + "DEF": [ + "ipconfigARP_USE_CLASH_DETECTION=0" + ] + } + + These Makefile.json files then can be turned into Makefiles for running + the proof by executing the make-proof-makefiles.py script. + """) + + +def process(folder, files): + json_content = load_json_config_file(os.path.join(folder, + "Configurations.json")) + try: + def_list = json_content["DEF"] + except KeyError: + LOGGER.error("Expected DEF as key in a Configurations.json files.") + return + for config in def_list: + logging.debug(config) + try: + configname = [name for name in config.keys() + if name != "EXPECTED"][0] + configbody = config[configname] + except (AttributeError, IndexError) as e: + LOGGER.error(e) + LOGGER.error(textwrap.dedent("""\ + The expected layout for an entry in the Configurations.json + file is a dictonary. Here is an example of the expected format: + + "DEF": + [ + {"disableClashDetection": ["ipconfigARP_USE_CLASH_DETECTION=0"]}, + {"enableClashDetection": ["ipconfigARP_USE_CLASH_DETECTION=1"]} + ] + """)) + LOGGER.error("The offending entry is %s", config) + return + new_config_folder = os.path.join(folder, "config_" + configname) + pathlib.Path(new_config_folder).mkdir(exist_ok=True, parents=True) + harness_copied = False + for file in files: + if file.endswith("harness.c"): + shutil.copy(os.path.join(folder, file), + os.path.join(new_config_folder, file)) + harness_copied = True + + if not harness_copied: + LOGGER.error("Could not find a harness in folder %s.", folder) + LOGGER.error("This folder is not processed do the end!") + return + # The order of keys must be maintained as otherwise the + # make_proof_makefiles script might fail. + current_config = collections.OrderedDict(json_content) + current_config["DEF"] = configbody + if "EXPECTED" in config.keys(): + current_config["EXPECTED"] = config["EXPECTED"] + else: + current_config["EXPECTED"] = True + with open(os.path.join(new_config_folder, "Makefile.json"), + "w") as output_file: + json.dump(current_config, output_file, indent=2) + + +def main(): + for fldr, _, fyles in os.walk("."): + if "Configurations.json" in fyles: + process(fldr, fyles) + + +if __name__ == '__main__': + logging.basicConfig(format="{script}: %(levelname)s %(message)s".format( + script=os.path.basename(__file__))) + main() diff --git a/FreeRTOS/Test/CBMC/proofs/make_proof_makefiles.py b/FreeRTOS/Test/CBMC/proofs/make_proof_makefiles.py new file mode 100755 index 000000000..846942ee4 --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/make_proof_makefiles.py @@ -0,0 +1,416 @@ +#!/usr/bin/env python3 +# +# Generation of Makefiles for CBMC proofs. +# +# Copyright (C) 2019 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 argparse +import ast +import collections +import json +import logging +import operator +import os +import os.path +import platform +import re +import sys +import textwrap +import traceback + + +# ______________________________________________________________________________ +# Compatibility between different python versions +# `````````````````````````````````````````````````````````````````````````````` + +# Python 3 doesn't have basestring +try: + basestring +except NameError: + basestring = str + +# ast.Num was deprecated in python 3.8 +_plat = platform.python_version().split(".") +if _plat[0] == "3" and int(_plat[1]) > 7: + ast_num = ast.Constant +else: + ast_num = ast.Num +# ______________________________________________________________________________ + + +def prolog(): + return textwrap.dedent("""\ + This script generates Makefiles that can be used either on Windows (with + NMake) or Linux (with GNU Make). The Makefiles consist only of variable + definitions; they are intended to be used with a common Makefile that + defines the actual rules. + + The Makefiles are generated from JSON specifications. These are simple + key-value dicts, but can contain variables and computation, as + well as comments (lines whose first character is "#"). If the + JSON file contains the following information: + + { + # 'T was brillig, and the slithy toves + "FOO": "BAR", + "BAZ": "{FOO}", + + # Did gyre and gimble in the wabe; + "QUUX": 30 + "XYZZY": "__eval 5 if {QUUZ} < 5 else min({QUUX}, 60)" + } + + then the resulting Makefile will look like + + H_FOO = BAR + H_BAZ = BAR + H_QUUX = 30 + H_XYZZY = 30 + + The language used for evaluation is highly restricted; arbitrary + python is not allowed. JSON values that are lists will be + joined with whitespace: + + { "FOO": ["BAR", "BAZ", "QUX"] } + + -> + + H_FOO = BAR BAZ QUX + + As a special case, if a key is equal to "DEF", "INC" (and maybe more, + read the code) the list of values is treated as a list of defines or + include paths. Thus, they have -D or /D, or -I or /I, prepended to them + as appropriate for the platform. + + + { "DEF": ["DEBUG", "FOO=BAR"] } + + on Linux -> + + H_DEF = -DDEBUG -DFOO=BAR + + Pathnames are written with a forward slash in the JSON file. In + each value, all slashes are replaced with backslashes if + generating Makefiles for Windows. If you wish to generate a + slash even on Windows, use two slashes---that will be changed + into a single forward slash on both Windows and Linux. + + { + "INC": [ "my/cool/directory" ], + "DEF": [ "HALF=//2" ] + } + + On Windows -> + + H_INC = /Imy\cool\directory + H_DEF = /DHALF=/2 + + When invoked, this script walks the directory tree looking for files + called "Makefile.json". It reads that file and dumps a Makefile in that + same directory. We assume that this script lives in the same directory + as a Makefile called "Makefile.common", which contains the actual Make + rules. The final line of each of the generated Makefiles will be an + include statement, including Makefile.common. + """) + +def load_json_config_file(file): + with open(file) as handle: + lines = handle.read().splitlines() + no_comments = "\n".join([line for line in lines + if line and not line.lstrip().startswith("#")]) + try: + data = json.loads(no_comments, + object_pairs_hook=collections.OrderedDict) + except json.decoder.JSONDecodeError: + traceback.print_exc() + logging.error("parsing file %s", file) + sys.exit(1) + return data + + +def dump_makefile(dyr, system): + data = load_json_config_file(os.path.join(dyr, "Makefile.json")) + + makefile = collections.OrderedDict() + + # Makefile.common expects a variable called OBJS_EXCEPT_HARNESS to be + # set to a list of all the object files except the harness. + if "OBJS" not in data: + logging.error( + "Expected a list of object files in %s/Makefile.json" % dyr) + exit(1) + makefile["OBJS_EXCEPT_HARNESS"] = " ".join( + o for o in data["OBJS"] if not o.endswith("_harness.goto")) + + so_far = collections.OrderedDict() + for name, value in data.items(): + if isinstance(value, list): + new_value = [] + for item in value: + new_value.append(compute(item, so_far, system, name, dyr, True)) + makefile[name] = " ".join(new_value) + else: + makefile[name] = compute(value, so_far, system, name, dyr) + + if (("EXPECTED" not in makefile.keys()) or + str(makefile["EXPECTED"]).lower() == "true"): + makefile["EXPECTED"] = "SUCCESSFUL" + elif str(makefile["EXPECTED"]).lower() == "false": + makefile["EXPECTED"] = "FAILURE" + makefile = ["H_%s = %s" % (k, v) for k, v in makefile.items()] + + # Deal with the case of a harness being nested several levels under + # the top-level proof directory, where the common Makefile lives + common_dir_path = "..%s" % _platform_choices[system]["path-sep"] + common_dir_path = common_dir_path * len(dyr.split(os.path.sep)[1:]) + + with open(os.path.join(dyr, "Makefile"), "w") as handle: + handle.write(("""{contents} + +{include} {common_dir_path}Makefile.common""").format( + contents="\n".join(makefile), + include=_platform_choices[system]["makefile-inc"], + common_dir_path=common_dir_path)) + + +def compute(value, so_far, system, key, harness, appending=False): + if not isinstance(value, (basestring, float, int)): + logging.error(wrap("""\ + in file %s, the key '%s' has value '%s', + which is of the wrong type (%s)"""), + os.path.join(harness, "Makefile.json"), key, + str(value), str(type(value))) + exit(1) + + value = str(value) + try: + var_subbed = value.format(**so_far) + except KeyError as e: + logging.error(wrap("""\ + in file %s, the key '%s' has value '%s', which + contains the variable %s, but that variable has + not previously been set in the file"""), + os.path.join(harness, "Makefile.json"), key, + value, str(e)) + exit(1) + + if var_subbed[:len("__eval")] != "__eval": + tmp = re.sub("//", "__DOUBLE_SLASH__", var_subbed) + tmp = re.sub("/", _platform_choices[system]["path-sep-re"], tmp) + evaluated = re.sub("__DOUBLE_SLASH__", "/", tmp) + else: + to_eval = var_subbed[len("__eval"):].strip() + logging.debug("About to evaluate '%s'", to_eval) + evaluated = eval_expr(to_eval, + os.path.join(harness, "Makefile.json"), + key, value) + + if key == "DEF": + final_value = "%s%s" % (_platform_choices[system]["define"], + evaluated) + elif key == "INC": + final_value = "%s%s" % (_platform_choices[system]["include"], + evaluated) + else: + final_value = evaluated + + # Allow this value to be used for future variable substitution + if appending: + try: + so_far[key] = "%s %s" % (so_far[key], final_value) + except KeyError: + so_far[key] = final_value + logging.debug("Appending final value '%s' to key '%s'", + final_value, key) + else: + so_far[key] = final_value + logging.info("Key '%s' set to final value '%s'", key, final_value) + + return final_value + + +def eval_expr(expr_string, harness, key, value): + """ + Safe evaluation of purely arithmetic expressions + """ + try: + tree = ast.parse(expr_string, mode="eval").body + except SyntaxError: + traceback.print_exc() + logging.error(wrap("""\ + in file %s at key '%s', value '%s' contained the expression + '%s' which is an invalid expression"""), harness, key, + value, expr_string) + exit(1) + + def eval_single_node(node): + logging.debug(node) + if isinstance(node, ast_num): + return node.n + # We're only doing IfExp, which is Python's ternary operator + # (i.e. it's an expression). NOT If, which is a statement. + if isinstance(node, ast.IfExp): + # Let's be strict and only allow actual booleans in the guard + guard = eval_single_node(node.test) + if guard is not True and guard is not False: + logging.error(wrap("""\ + in file %s at key '%s', there was an invalid guard + for an if statement."""), harness, key) + exit(1) + if guard: + return eval_single_node(node.body) + return eval_single_node(node.orelse) + if isinstance(node, ast.Compare): + left = eval_single_node(node.left) + # Don't allow expressions like (a < b) < c + right = eval_single_node(node.comparators[0]) + op = eval_single_node(node.ops[0]) + return op(left, right) + if isinstance(node, ast.BinOp): + left = eval_single_node(node.left) + right = eval_single_node(node.right) + op = eval_single_node(node.op) + return op(left, right) + if isinstance(node, ast.Call): + valid_calls = { + "max": max, + "min": min, + } + if node.func.id not in valid_calls: + logging.error(wrap("""\ + in file %s at key '%s', there was an invalid + call to %s()"""), harness, key, node.func.id) + exit(1) + left = eval_single_node(node.args[0]) + right = eval_single_node(node.args[1]) + return valid_calls[node.func.id](left, right) + try: + return { + ast.Eq: operator.eq, + ast.NotEq: operator.ne, + ast.Lt: operator.lt, + ast.LtE: operator.le, + ast.Gt: operator.gt, + ast.GtE: operator.ge, + + ast.Add: operator.add, + ast.Sub: operator.sub, + ast.Mult: operator.mul, + # Use floordiv (i.e. //) so that we never need to + # cast to an int + ast.Div: operator.floordiv, + }[type(node)] + except KeyError: + logging.error(wrap("""\ + in file %s at key '%s', there was expression that + was impossible to evaluate"""), harness, key) + exit(1) + + return eval_single_node(tree) + + +_platform_choices = { + "linux": { + "platform": "linux", + "path-sep": "/", + "path-sep-re": "/", + "define": "-D", + "include": "-I", + "makefile-inc": "include", + }, + "windows": { + "platform": "win32", + "path-sep": "\\", + "path-sep-re": re.escape("\\"), + "define": "/D", + "include": "/I", + "makefile-inc": "!INCLUDE", + }, +} +# Assuming macos is the same as linux +_mac_os = dict(_platform_choices["linux"]) +_mac_os["platform"] = "darwin" +_platform_choices["macos"] = _mac_os + + +def default_platform(): + for arg_string, os_data in _platform_choices.items(): + if sys.platform == os_data["platform"]: + return arg_string + return "linux" + + +_args = [{ + "flags": ["-s", "--system"], + "metavar": "OS", + "choices": _platform_choices, + "default": str(default_platform()), + "help": textwrap.dedent("""\ + which operating system to generate makefiles for. + Defaults to the current platform (%(default)s); + choices are {choices}""").format( + choices="[%s]" % ", ".join(_platform_choices)), +}, { + "flags": ["-v", "--verbose"], + "help": "verbose output", + "action": "store_true", +}, { + "flags": ["-w", "--very-verbose"], + "help": "very verbose output", + "action": "store_true", + }] + + +def get_args(): + pars = argparse.ArgumentParser( + description=prolog(), + formatter_class=argparse.RawDescriptionHelpFormatter) + for arg in _args: + flags = arg.pop("flags") + pars.add_argument(*flags, **arg) + return pars.parse_args() + + +def set_up_logging(args): + fmt = "{script}: %(levelname)s %(message)s".format( + script=os.path.basename(__file__)) + if args.very_verbose: + logging.basicConfig(format=fmt, level=logging.DEBUG) + elif args.verbose: + logging.basicConfig(format=fmt, level=logging.INFO) + else: + logging.basicConfig(format=fmt, level=logging.WARNING) + +def wrap(string): + return re.sub(r"\s+", " ", re.sub("\n", " ", string)) + +def main(): + args = get_args() + set_up_logging(args) + + for root, _, fyles in os.walk("."): + if "Makefile.json" in fyles: + dump_makefile(root, args.system) + + +if __name__ == "__main__": + main() diff --git a/FreeRTOS/Test/CBMC/proofs/make_remove_makefiles.py b/FreeRTOS/Test/CBMC/proofs/make_remove_makefiles.py new file mode 100755 index 000000000..12d0c72f1 --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/make_remove_makefiles.py @@ -0,0 +1,48 @@ +#!/usr/bin/env python3 +# +# Removing the generated Makefiles and cbmc-batch.yaml files. +# +# Copyright (C) 2019 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 + +from make_cbmc_batch_files import remove_cbmc_yaml_files + +def main(): + try: + os.remove("Makefile.common") + except FileNotFoundError: + pass + + for root, _, files in os.walk("."): + # We do not want to remove hand-written Makefiles, so + # only remove Makefiles that are in the same directory as + # a Makefile.json. Such Makefiles are generated from the + # JSON file. + if "Makefile.json" in files: + try: + os.remove(os.path.join(root, "Makefile")) + except FileNotFoundError: + pass + +if __name__ == "__main__": + remove_cbmc_yaml_files() + main() diff --git a/FreeRTOS/Test/CBMC/proofs/make_type_header_files.py b/FreeRTOS/Test/CBMC/proofs/make_type_header_files.py new file mode 100755 index 000000000..a8ac66384 --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/make_type_header_files.py @@ -0,0 +1,162 @@ +#!/usr/bin/env python3 +# +# Compute type header files for c modules +# +# Copyright (C) 2019 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 argparse +import logging +import os +import re +import shutil +import subprocess +import sys +from tempfile import TemporaryDirectory + +def epilog(): + return """\ + This program dumps a header file containing the types and macros + contained in the C file passed as input. It uses `goto-instrument` + from the CBMC tool suite instead of the preprocessor, to dump types + and other constructs as well as preprocessor directives. + + This program should be used in cases where types or macros declared + for internal use in a C file use are needed to write a test harness + or CBMC proof. The intention is that the build process will run + this program to dump the header file, and the proof will #include + the header. + """ + +_DEFINE_REGEX_HEADER = re.compile(r"\s*#\s*define\s*([\w]+)") + + +def get_module_name(fyle): + base = os.path.basename(fyle) + return base.split(".")[0] + + +def collect_defines(fyle): + collector_result = "" + continue_define = False + in_potential_def_scope = "" + potential_define = False + potential_define_confirmed = False + with open(fyle) as in_file: + for line in in_file: + matched = _DEFINE_REGEX_HEADER.match(line) + if line.strip().startswith("#if"): + potential_define = True + in_potential_def_scope += line + elif line.strip().startswith("#endif") and potential_define: + if potential_define_confirmed: + in_potential_def_scope += line + collector_result += in_potential_def_scope + in_potential_def_scope = "" + potential_define = False + potential_define_confirmed = False + elif matched and potential_define: + potential_define_confirmed = True + in_potential_def_scope += line + elif matched or continue_define: + continue_define = line.strip("\n").endswith("\\") + collector_result += line + elif potential_define: + in_potential_def_scope += line + return collector_result + + +def make_header_file(goto_binary, fyle, target_folder): + fyle = os.path.normpath(fyle) + with TemporaryDirectory() as tmpdir: + module = get_module_name(fyle) + header_file = "{}_datastructure.h".format(module) + + drop_header_cmd = ["goto-instrument", + "--dump-c-type-header", + module, + goto_binary, + header_file] + res = subprocess.run(drop_header_cmd, + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, + universal_newlines=True, + cwd=tmpdir) + if res.returncode: + logging.error("Dumping type header for file '%s' failed", fyle) + logging.error("The command `%s` returned %s", + drop_header_cmd, + res.stdout) + logging.error("The return code is %d", int(res.returncode)) + sys.exit(1) + + header = os.path.normpath(os.path.join(tmpdir, header_file)) + collected = collect_defines(fyle) + logging.debug("Dumping the following header file to '%s':\n%s\n" + "// END GENERATED HEADER FILE", header, collected) + with open(header, "a") as out: + print(collected, file=out) + + target_file = os.path.normpath(os.path.join(target_folder, header_file)) + shutil.move(header, target_file) + + +_ARGS = [{ + "flags": ["--c-file"], + "metavar": "F", + "help": "source file to extract types and headers from", + "required": True +}, { + "flags": ["--binary"], + "metavar": "B", + "help": "file compiled from the source file with CBMC's goto-cc compiler", + "required": True +}, { + "flags": ["--out-dir"], + "metavar": "D", + "help": ("directory to write the generated header file to " + "(default: %(default)s)"), + "default": os.path.abspath(os.getcwd()), +}, { + "flags": ["--verbose", "-v"], + "help": "verbose output", + "action": "store_true" +}] + + +if __name__ == '__main__': + pars = argparse.ArgumentParser( + epilog=epilog(), + description="Dump a C file's types and macros to a separate file") + for arg in _ARGS: + flags = arg.pop("flags") + pars.add_argument(*flags, **arg) + + args = pars.parse_args() + + fmt = "{script}: %(levelname)s %(message)s".format( + script=os.path.basename(__file__)) + if args.verbose: + logging.basicConfig(format=fmt, level=logging.DEBUG) + else: + logging.basicConfig(format=fmt, level=logging.INFO) + + make_header_file(args.binary, args.c_file, args.out_dir) diff --git a/FreeRTOS/Test/CBMC/proofs/ninja.py b/FreeRTOS/Test/CBMC/proofs/ninja.py new file mode 100755 index 000000000..4bfd3c8d4 --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/ninja.py @@ -0,0 +1,219 @@ +#!/usr/bin/env python3 + +""" +Write a ninja build file to generate reports for cbmc proofs. + +Given a list of folders containing cbmc proofs, write a ninja build +file the generate reports for these proofs. The list of folders may +be given on the command line, in a json file, or found in the file +system. +""" + +# Add task pool + +import sys +import os +import platform +import argparse +import json + +################################################################ +# The command line parser + +def argument_parser(): + """Return the command line parser.""" + + parser = argparse.ArgumentParser( + description='Generate ninja build file for cbmc proofs.', + epilog=""" + Given a list of folders containing cbmc proofs, write a ninja build + file the generate reports for these proofs. The list of folders may + be given on the command line, in a json file, or found in the file + system. + In the json file, there should be a dict mapping the key "proofs" + to a list of folders containing proofs. + The file system, all folders folders under the current directory + containing a file named 'cbmc-batch.yaml' is considered a + proof folder. + This script assumes that the proof is driven by a Makefile + with targets goto, cbmc, coverage, property, and report. + This script does not work with Windows and Visual Studio. + """ + ) + parser.add_argument('folders', metavar='PROOF', nargs='*', + help='Folder containing a cbmc proof') + parser.add_argument('--proofs', metavar='JSON', + help='Json file listing folders containing cbmc proofs') + return parser + +################################################################ +# The list of folders containing proofs +# +# The list of folders will be taken from +# 1. the list PROOFS defined here or +# 2. the command line +# 3. the json file specified on the command line containing a +# dict mapping the key JSON_KEY to a list of folders +# 4. the folders below the current directory containing +# a file named FS_KEY +# + +PROOFS = [ +] + +JSON_KEY = 'proofs' +FS_KEY = 'cbmc-batch.yaml' + +def find_proofs_in_json_file(filename): + """Read the list of folders containing proofs from a json file.""" + + if not filename: + return [] + try: + with open(filename) as proofs: + return json.load(proofs)[JSON_KEY] + except (FileNotFoundError, KeyError): + raise UserWarning("Can't find key {} in json file {}".format(JSON_KEY, filename)) + except json.decoder.JSONDecodeError: + raise UserWarning("Can't parse json file {}".format(filename)) + +def find_proofs_in_filesystem(): + """Locate the folders containing proofs in the filesystem.""" + + proofs = [] + for root, _, files in os.walk('.'): + if FS_KEY in files: + proofs.append(os.path.normpath(root)) + return proofs + +################################################################ +# The strings used to write sections of the ninja file + +NINJA_RULES = """ +################################################################ +# task pool to force sequential builds of goto binaries + +pool goto_pool + depth = 1 + +################################################################ +# proof target rules + +rule build_goto + command = make -C ${folder} goto + pool = goto_pool + +rule build_cbmc + command = make -C ${folder} cbmc + +rule build_coverage + command = make -C ${folder} coverage + +rule build_property + command = make -C ${folder} property + +rule build_report + command = make -C ${folder} report + +rule clean_folder + command = make -C ${folder} clean + +rule veryclean_folder + command = make -C ${folder} veryclean + +rule open_proof + command = open ${folder}/html/index.html + +""" + +NINJA_BUILDS = """ +################################################################ +# {folder} proof targets + +build {folder}/{entry}.goto: build_goto + folder={folder} + +build {folder}/cbmc.txt: build_cbmc {folder}/{entry}.goto + folder={folder} + +build {folder}/coverage.xml: build_coverage {folder}/{entry}.goto + folder={folder} + +build {folder}/property.xml: build_property {folder}/{entry}.goto + folder={folder} + +build {folder}/html/index.html: build_report {folder}/{entry}.goto {folder}/cbmc.txt {folder}/coverage.xml {folder}/property.xml + folder={folder} + +build clean_{folder}: clean_folder + folder={folder} + +build veryclean_{folder}: veryclean_folder + folder={folder} + +build open_{folder}: open_proof + folder={folder} + +build {folder}: phony {folder}/html/index.html + +default {folder} + +""" + +NINJA_GLOBALS = """ +################################################################ +# global targets + +build clean: phony {clean_targets} + +build veryclean: phony {veryclean_targets} + +build open: phony {open_targets} +""" + +################################################################ +# The main function + +def get_entry(folder): + """Find the name of the proof in the proof Makefile.""" + + with open('{}/Makefile'.format(folder)) as makefile: + for line in makefile: + if line.strip().lower().startswith('entry'): + return line[line.find('=')+1:].strip() + if line.strip().lower().startswith('h_entry'): + return line[line.find('=')+1:].strip() + raise UserWarning("Can't find ENTRY in {}/Makefile".format(folder)) + +def write_ninja_build_file(): + """Write a ninja build file to generate proof results.""" + + if platform.system().lower() == 'windows': + print("This script does not run on Windows.") + sys.exit() + + args = argument_parser().parse_args() + + proofs = (PROOFS or + args.folders or + find_proofs_in_json_file(args.proofs) or + find_proofs_in_filesystem()) + + with open('build.ninja', 'w') as ninja: + ninja.write(NINJA_RULES) + for proof in proofs: + entry = get_entry(proof) + ninja.write(NINJA_BUILDS.format(folder=proof, entry=entry)) + targets = lambda kind, folders: ' '.join( + ['{}_{}'.format(kind, folder) for folder in folders] + ) + ninja.write(NINJA_GLOBALS.format( + clean_targets=targets('clean', proofs), + veryclean_targets=targets('veryclean', proofs), + open_targets=targets('open', proofs) + )) + +################################################################ + +if __name__ == "__main__": + write_ninja_build_file() diff --git a/FreeRTOS/Test/CBMC/proofs/prepare.py b/FreeRTOS/Test/CBMC/proofs/prepare.py new file mode 100755 index 000000000..58f9903db --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/prepare.py @@ -0,0 +1,115 @@ +#!/usr/bin/env python3 +# +# Python script for preparing the code base for the CBMC proofs. +# +# Copyright (C) 2019 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 logging +import os +import sys +import textwrap +from subprocess import CalledProcessError + +from make_common_makefile import main as make_common_file +from make_configuration_directories import main as process_configurations +from make_proof_makefiles import main as make_proof_files +from make_cbmc_batch_files import create_cbmc_yaml_files + +CWD = os.getcwd() +sys.path.append(os.path.normpath(os.path.join(CWD, "..", "patches"))) + +#from compute_patch import create_patches +#from compute_patch import DirtyGitError +#from compute_patch import PatchCreationError +from patches_constants import HEADERS + +from compute_patch import find_all_defines +from compute_patch import manipulate_headerfile + +import patch + +PROOFS_DIR = os.path.dirname(os.path.abspath(__file__)) + +LOGGER = logging.getLogger("PrepareLogger") + +################################################################ + +def patch_headers(headers): + """Patch headers so we can define symbols on the command line. + + When building for CBMC, it is convenient to define symbols on the + command line and know that these definitions will override the + definitions of the same symbols in header files. + + The create_patches function takes a list of header files, searches + the Makefile.json files for symbols that will be defined in the + Makefiles, and creates patch files that protect the definition of + those symbols in header files with #ifndef/#endif. In this way, + command line definitions will override header file definitions. + + The create_patches function, however, depends on the fact that all + header files being modified are included in the top-level git + repository. This assumption is violated if header files live in + submodules. + + This function just updates the header files in place without + creating patch files. One potential vulnerability of this + function is that it could cause preexisting patch files to fail if + they patch a file being modified here. + """ + defines = find_all_defines() + for header in headers: + manipulate_headerfile(defines, header) + +################################################################ + +def build(): + process_configurations() + make_common_file() + make_proof_files() + try: + create_cbmc_yaml_files() + except CalledProcessError as e: + logging.error(textwrap.dedent("""\ + An error occured during cbmc-batch generation. + The error message is: {} + """.format(str(e)))) + exit(1) + + # Patch headers directly instead of creating patch files. + patch.patch() + patch_headers(HEADERS) + + #try: + # create_patches(HEADERS) + #except (DirtyGitError, PatchCreationError) as e: + # logging.error(textwrap.dedent("""\ + # An error occured during patch creation. + # The error message is: {} + # """.format(str(e)))) + # exit(1) + +################################################################ + +if __name__ == '__main__': + logging.basicConfig(format="{script}: %(levelname)s %(message)s".format( + script=os.path.basename(__file__))) + build() diff --git a/FreeRTOS/Test/CBMC/proofs/utility/memory_assignments.c b/FreeRTOS/Test/CBMC/proofs/utility/memory_assignments.c new file mode 100644 index 000000000..6bcb9319a --- /dev/null +++ b/FreeRTOS/Test/CBMC/proofs/utility/memory_assignments.c @@ -0,0 +1,24 @@ +#define ensure_memory_is_valid( px, length ) (px != NULL) && __CPROVER_w_ok((px), length) + +/* Implementation of safe malloc which returns NULL if the requested size is 0. + Warning: The behavior of malloc(0) is platform dependent. + It is possible for malloc(0) to return an address without allocating memory.*/ +void *safeMalloc(size_t xWantedSize) { + return nondet_bool() ? malloc(xWantedSize) : NULL; +} + +/* Memory assignment for FreeRTOS_Socket_t */ +FreeRTOS_Socket_t * ensure_FreeRTOS_Socket_t_is_allocated () { + FreeRTOS_Socket_t *pxSocket = safeMalloc(sizeof(FreeRTOS_Socket_t)); + if (ensure_memory_is_valid(pxSocket, sizeof(FreeRTOS_Socket_t))) { + pxSocket->u.xTCP.rxStream = safeMalloc(sizeof(StreamBuffer_t)); + pxSocket->u.xTCP.txStream = safeMalloc(sizeof(StreamBuffer_t)); + pxSocket->u.xTCP.pxPeerSocket = safeMalloc(sizeof(FreeRTOS_Socket_t)); + } + return pxSocket; +} + +/* Memory assignment for FreeRTOS_Network_Buffer */ +NetworkBufferDescriptor_t * ensure_FreeRTOS_NetworkBuffer_is_allocated () { + return safeMalloc(sizeof(NetworkBufferDescriptor_t)); +} diff --git a/FreeRTOS/Test/CBMC/windows/README.md b/FreeRTOS/Test/CBMC/windows/README.md new file mode 100644 index 000000000..e9f415060 --- /dev/null +++ b/FreeRTOS/Test/CBMC/windows/README.md @@ -0,0 +1,2 @@ +This directory contains include files used by the CBMC proofs: +* Windows.h and WinBase.h are include files used to build FreeRTOS (the parts we currently test) on Linux
\ No newline at end of file diff --git a/FreeRTOS/Test/CBMC/windows/WinBase.h b/FreeRTOS/Test/CBMC/windows/WinBase.h new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/FreeRTOS/Test/CBMC/windows/WinBase.h diff --git a/FreeRTOS/Test/CBMC/windows/Windows.h b/FreeRTOS/Test/CBMC/windows/Windows.h new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/FreeRTOS/Test/CBMC/windows/Windows.h diff --git a/FreeRTOS/Test/CBMC/windows/direct.h b/FreeRTOS/Test/CBMC/windows/direct.h new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/FreeRTOS/Test/CBMC/windows/direct.h @@ -0,0 +1 @@ + |