-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add CN specs to MKM #142
base: main
Are you sure you want to change the base?
Add CN specs to MKM #142
Conversation
5a2dcc7
to
0e65e31
Compare
667e47c
to
a4f9a2a
Compare
a4f9a2a
to
218a2f2
Compare
@peterohanley @podhrmic PR ready to be re-reviewed when you have time. We now supports verification and functional correctness proofs of MKM, and testing of MKM. I've removed a lot of the limitations that existed before (but introduced some new ones caused by the test generator...). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The changes to failing malloc are big improvements.
I tried this on Linux (running
It seems like I was able to work around this by patching MKM to not use Click to see diffdiff --git a/components/include/wars.h b/components/include/wars.h
index f8f476c..81e230f 100644
--- a/components/include/wars.h
+++ b/components/include/wars.h
@@ -77,11 +77,4 @@
// accepts this but CN rejects it
#define WAR_CN_437 1
-#ifdef WAR_CN_437
-// this is required so we can mention FILE* parameters
-struct _IO_FILE {
- int x;
-};
-#endif
-
#endif // __CN_WARS_H__
diff --git a/components/mission_key_management/client.c b/components/mission_key_management/client.c
index f9e4426..71690d8 100644
--- a/components/mission_key_management/client.c
+++ b/components/mission_key_management/client.c
@@ -8,7 +8,6 @@
#include <sys/socket.h>
#include <unistd.h>
-#include <stdio.h>
//SYSTEM_HEADERS
// ^^^ magic string used during preprocessing - do not move / remove
@@ -18,9 +17,12 @@
#if ! defined(CN_ENV)
# include <sys/types.h>
# include <sys/epoll.h>
+# include <stdio.h>
+# define LOG(...) (fprintf(stderr, __VA_ARGS__))
#else
# include "cn_stubs.h"
# include "cn_array_utils.h"
+# define LOG(...) /* nothing */
#endif
// TODO `Alloc` construct not supported by `cn test`
@@ -445,11 +447,11 @@ $*/
c->response, c->response + MEASURE_SIZE);
if (c->key == NULL) {
// No matching key was found for this request.
- fprintf(stderr, "client %d: error: bad request for key %u\n", c->fd, c->key_id[0]);
+ LOG("client %d: error: bad request for key %u\n", c->fd, c->key_id[0]);
return RES_ERROR;
}
client_change_state(c, CS_SEND_KEY);
- fprintf(stderr, "client %d: sending key %u\n", c->fd, c->key_id[0]);
+ LOG("client %d: sending key %u\n", c->fd, c->key_id[0]);
break;
case CS_SEND_KEY:
diff --git a/components/mission_key_management/cn_stubs.h b/components/mission_key_management/cn_stubs.h
index 17025ea..facafbd 100644
--- a/components/mission_key_management/cn_stubs.h
+++ b/components/mission_key_management/cn_stubs.h
@@ -80,10 +80,6 @@ $*/
// From `stdio.h`
-/*$ spec fprintf(pointer f, pointer s);
-requires true;
-ensures true;
-$*/
#if defined(CN_TEST)
# define fprintf(...) 0
#endif
@@ -129,14 +125,7 @@ $*/
# define read(f,b,c) _read_uint8_t(f,b,c)
#else
ssize_t _read_mock(void *buf, size_t count) {
- // Fake file descriptor for use during testing
- FILE *file = tmpfile();
- if (!file) {
- perror("tmpfile failed (client_read)");
- return -1;
- }
- int tmp_fd = fileno(file);
- return read(tmp_fd, buf, count);
+ return 0;
}
#define read(f,b,c) _read_mock(b,c)
#endif
@@ -155,14 +144,7 @@ $*/
# define write(f,b,c) _write_uint8_t(f,b,c)
#else
ssize_t _write_mock(const void *buf, size_t count) {
- // Fake file descriptor for use during testing
- FILE *file = tmpfile();
- if (!file) {
- perror("tmpfile failed (client_read)");
- return -1;
- }
- int tmp_fd = fileno(file);
- return write(tmp_fd, buf, count);
+ return count;
}
#define write(f,b,c) _write_mock(b,c)
#endif |
@spernsteiner that is a good catch. We will need to add a CI job to run the test generation, which will probably show a couple of other issues. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good! Minor comments above. Still need to add a CI job that runs the tests.
What do you think about linking the remaining TODOs to CN tickets, such that we known what needs to be fixed?
@@ -2,6 +2,18 @@ | |||
#define CN_ARRAY_UTILS_H_ | |||
|
|||
/*$ | |||
predicate (map<u64,u8>) Array_Owned_u8 (pointer p, u64 l) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is already a similar predicate - did you mean to use this one?
return Arr; | ||
} | ||
|
||
predicate (map<u64,u8>) Array_Block_u8 (pointer p, u64 l) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as above
@@ -69,4 +69,31 @@ ensures | |||
take i = each(u64 j; j >= 0u64 && j < n) {Block<uint8_t>(array_shift<uint8_t>(return, j))}; | |||
$*/ | |||
|
|||
/*$ | |||
datatype OptionMemory { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would like to have at least a sentence of description for each predicate, similar to what Gus did for array_utils.h. I know this might be obvious to you, but this will really pay off during the transition. Maybe @peterohanley can help here?
# define NULL ((void *)0) | ||
#endif | ||
|
||
/* TODO list: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am assuming you are still actively working on this TODO?
Also, this list should be a part of the PR description rather than being hidden in the code.
SomeClientObject {struct client obj}, | ||
NoneClientObject {} | ||
} | ||
predicate (OptionClientObject) OptionClientNew(pointer p, i32 fd, i32 state) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it useful to have the predicates in a separate file?
// Pure predicate representing valid states of `enum client_state`. | ||
// CN could easily generate this automatically (see #796) | ||
/*$ | ||
function (boolean) ValidState (u32 state) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for the comments!
/* | ||
start: | ||
┌────────────────┐ | ||
┌─►│ CS_RECV_KEY_ID ├──────┐ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice diagram!
ensures true; | ||
$*/ | ||
#if defined(CN_TEST) | ||
# define fprintf(...) 0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All these should defines really be in some sort of CN standard library...
This PR adds CN functional specifications to the MKM code in
client.c
, as well as various supporting files. These specifications are intended to be run-time tested as well as verified.Files:
client.c
- target function definitionsclient.h
- types, and CN predicates defining the typescn_stubs.h
- specifications and redefinitions for various library functions that can't be supported directlyrun-cn-test.sh
- run the CN test generator using the necessary flagsprocess-cn-test.sh
- run the preprocessor. Called byrun-cn-test.sh
Unfortunately, the CN verifier and test generators require different code-level annotations at various points. We handle this using a pair of macros:
CN_ENV
- set when calling CN in either verify or test modesCN_TEST
- set when calling CN in test modeTesting the PR
To run the verifier, run:
Note this may be quite slow. It takes around 3m30s to complete on my newish MBP.
To run the tests, run:
Outstanding bugs
TheFIXEDrun-cn-test.sh
script pauses during execution and only continues when I pressreturn
. I assume this is due to some call inclient.c
which is blocking, but I haven't figured out the culprit yet.TODO
notes. These generally indicate places I'm working around a limitation in CN of some kind. But some of these might be possible to resolve.Changes: