Skip to content
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

Enclave host compatibility check #2532

Merged
merged 18 commits into from
May 6, 2021

Conversation

jumaffre
Copy link
Contributor

@jumaffre jumaffre commented Apr 28, 2021

Resolves #1307

We now check that the enclave and the host have been built from the exact same commit.

The check is run by the enclave so that we don't have to deal with the awkward ECALL handling of out strings (see https://github.com/openenclave/openenclave/blob/cd72fd7069488ba6f453c8f5f47bd9fd9a6e6c0d/docs/GettingStartedDocs/Edger8rGettingStarted.md#you-are-on-your-own), but at the cost of not being able to report a useful error message when the version check fails (enclave log message is not output by the host as too early in the enclave creation process). I also tried to delay the point at which the version check is done, so that we can output a useful error message, but it seems too late and the node has already done a fair bit of work by then. Edit: the enclave now returns a specific error code on the first ECALL, that the host can print.

As always, feedback welcome!

@jumaffre jumaffre requested a review from a team as a code owner April 28, 2021 15:38
Copy link

@wintersteiger wintersteiger left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the only way to get nice/meaningful error messages for early failures like this, is to return an error code (or string?) from enclave_create_node instead of just a bool.

@ghost
Copy link

ghost commented Apr 28, 2021

enclave_host_compat@24870 aka 20210506.7 vs main ewma over 20 builds from 24526 to 24849

Click to see table
build_id build_number sb_sgx_cft^ sb_sgx_cft_mem sb_sgx_bft^ sb_sgx_bft_mem sb_ws_sgx_cft^ sb_ws_sgx_cft_mem sb_sig_sgx_cft^ sb_sig_sgx_cft_mem tpcc_sgx_cft^ tpcc_sgx_cft_mem tpcc_sgx_bft^ tpcc_sgx_bft_mem ls_sgx_cft^ ls_sgx_cft_mem ls_ws_sgx_cft^ ls_ws_sgx_cft_mem ls_jwt_sgx_cft^ ls_jwt_sgx_cft_mem ls_js_sgx_cft^ ls_js_sgx_cft_mem ls_js_jwt_sgx_cft^ ls_js_jwt_sgx_cft_mem CHAMP put (/s)^ CHAMP get (/s)^
24526 20210429.15 29339.9 1.29803e+07 14726.7 3.7884e+07 33436.9 1.32424e+07 5439.19 1.0621e+07 6463.56 9.37206e+07 3300.53 1.9019e+08 23574.1 1.76989e+07 28025.5 1.76989e+07 4235.43 1.48153e+07 1978.29 8.52384e+06 1470.07 7.99955e+06 1.35314e+06 3.61837e+07
24544 20210429.18 26808.2 1.32424e+07 14938.1 4.10297e+07 33268.6 1.32424e+07 4866.27 1.00967e+07 6325.62 9.13613e+07 3408.75 1.52965e+08 24792.1 1.82232e+07 29967.8 1.76989e+07 4401.18 1.48153e+07 2011.91 8.2617e+06 1451.97 7.99955e+06 1.3708e+06 3.59292e+07
24551 20210429.21 25439 1.27181e+07 13367.6 3.7884e+07 28387.9 1.32424e+07 4977.33 1.03588e+07 6486.59 9.18856e+07 2891.19 2.05656e+08 23363 1.71746e+07 30101.9 1.76989e+07 3925.77 1.4291e+07 2075.49 8.52384e+06 1458.71 7.99955e+06 1.34215e+06 3.63121e+07
24567 20210429.25 26991 1.29803e+07 13575.8 3.86704e+07 33216.1 1.32424e+07 4860.98 1.0621e+07 6486.62 9.16235e+07 3411.9 1.77082e+08 24125.5 1.74367e+07 29101.7 1.7961e+07 4228.48 1.45532e+07 2077.86 8.2617e+06 1453.77 9.31027e+06 1.34497e+06 3.62478e+07
24584 20210430.1 28953.8 1.32424e+07 14670.6 3.7884e+07 30152 1.35046e+07 4796.8 1.0621e+07 6605.36 9.16235e+07 3323.05 1.47722e+08 23001.3 1.76989e+07 29445.5 1.76989e+07 4242.52 1.45532e+07 2058.09 8.52384e+06 1451.77 9.57242e+06 1.34844e+06 3.61199e+07
24587 20210430.2 28120.1 1.29803e+07 14524.9 3.94568e+07 34453.3 1.35046e+07 4920.3 1.00967e+07 6723.07 9.26721e+07 3030.36 1.9753e+08 22394.7 1.76989e+07 29226.1 1.7961e+07 3868.71 1.4291e+07 2007.56 1.00967e+07 1423.19 7.99955e+06 1.30611e+06 3.59292e+07
24604 20210430.7 26052.8 1.29803e+07 13873.6 3.81461e+07 34375.7 1.35046e+07 5276.97 1.21939e+07 6385.08 9.16235e+07 3353.43 1.78131e+08 24343.7 1.76989e+07 29897.1 1.76989e+07 3859.3 1.4291e+07 2052.38 8.52384e+06 1402.32 7.99955e+06 1.34294e+06 3.62471e+07
24616 20210430.10 28306.6 1.29803e+07 14294.7 3.76218e+07 31792.8 1.32424e+07 4471.42 1.00967e+07 6558.14 9.05749e+07 3426.68 1.50606e+08 22784.9 1.76989e+07 28840.2 1.76989e+07 4207.73 1.45532e+07 1965.97 8.52384e+06 1400.25 7.73741e+06 1.34276e+06 3.62478e+07
24640 20210430.18 24936.4 1.32424e+07 13727.2 3.76218e+07 32701.6 1.32424e+07 4841.66 1.00967e+07 6510.91 9.26721e+07 3346.24 1.68956e+08 23653.7 1.7961e+07 30023.9 1.76989e+07 4102.44 1.50774e+07 2039.69 8.52384e+06 1455.89 7.99955e+06 1.35538e+06 3.63121e+07
24665 20210430.25 28071.2 1.27181e+07 13753.2 3.73597e+07 31916.5 1.29803e+07 4528.1 1.03588e+07 6462.63 9.16235e+07 3412.93 1.67383e+08 22795.5 1.76989e+07 27710.3 1.74367e+07 4214.67 1.48153e+07 2107.05 1.11453e+07 1457.57 7.73741e+06 1.34303e+06 3.54933e+07
24682 20210504.1 29888.9 1.29803e+07 14073.7 4.10297e+07 33852.8 1.32424e+07 4887.24 1.00967e+07 6742.63 9.13613e+07 3472.05 1.73675e+08 23470.9 1.74367e+07 29675.4 1.76989e+07 4036.84 1.45532e+07 1993.47 8.2617e+06 1481.98 9.57242e+06 1.34879e+06 3.62478e+07
24697 20210504.6 29528.4 1.29803e+07 14204.3 3.81461e+07 31933.9 1.32424e+07 4998.52 1.03588e+07 6717.63 9.26721e+07 3052.7 1.92549e+08 23698 1.74367e+07 30904 1.7961e+07 4118.71 1.48153e+07 2064.94 8.52384e+06 1476.95 7.99955e+06 1.33429e+06 3.61199e+07
24710 20210504.10 27022.3 1.29803e+07 13560.2 3.84083e+07 34000.8 1.32424e+07 4877.92 1.00967e+07 6808.59 9.08371e+07 3395.8 1.5113e+08 24362.4 1.76989e+07 31117 1.7961e+07 4363.37 1.50774e+07 2033.52 8.2617e+06 1460 7.73741e+06 1.3471e+06 3.61199e+07
24720 20210504.13 28953.3 1.29803e+07 14669.2 3.89325e+07 31365.6 1.37667e+07 5500.38 1.0621e+07 6718.63 9.29342e+07 3273 1.94122e+08 24156.4 1.7961e+07 30811.4 1.7961e+07 3973.07 1.4291e+07 2046.89 8.52384e+06 1433.72 9.57242e+06 1.33839e+06 3.63121e+07
24736 20210504.18 29628.9 1.32424e+07 14578.9 3.81461e+07 30879.8 1.32424e+07 4980.43 1.00967e+07 6760.34 9.29342e+07 3375.01 1.54276e+08 22484.6 1.74367e+07 28098.4 1.76989e+07 3666.12 1.45532e+07 1931.55 8.2617e+06 1485.37 8.2617e+06 1.33909e+06 3.56794e+07
24741 20210505.1 28538 1.29803e+07 13852.7 3.84083e+07 31124.8 1.32424e+07 4970.05 9.83456e+06 6669.33 9.31964e+07 3415.98 1.84685e+08 21815.1 1.76989e+07 30016.6 1.92717e+07 4224.52 1.45532e+07 2099.09 8.52384e+06 1457.55 7.99955e+06 1.35243e+06 3.56168e+07
24756 20210505.6 25497.4 1.29803e+07 13753.9 3.81461e+07 31719.2 1.32424e+07 4697.37 1.0621e+07 6468.75 9.16235e+07 3306.09 1.86257e+08 22092.6 1.7961e+07 28258.8 1.95339e+07 4185.42 1.45532e+07 2078.04 1.19317e+07 1440.07 7.99955e+06 1.32247e+06 3.62471e+07
24831 20210505.24 25054.3 1.29803e+07 14190 3.76218e+07 32868.8 1.32424e+07 4787.67 1.03588e+07 6385.84 9.16235e+07 3254.5 1.82325e+08 25319.8 1.90096e+07 28493.7 1.82232e+07 3848.57 1.45532e+07 1979.01 8.2617e+06 1453.11 9.83456e+06 1.35064e+06 3.61199e+07
24838 20210505.26 28940.4 1.29803e+07 14131.6 3.9719e+07 34667.2 1.37667e+07 4932.21 1.00967e+07 6495.3 9.21478e+07 3326.84 1.62665e+08 24739.6 1.74367e+07 29035.1 1.76989e+07 4107.17 1.40289e+07 2052.02 8.52384e+06 1459.81 7.73741e+06 1.34417e+06 3.62471e+07
24849 20210506.1 27714.6 1.29803e+07 14433.4 4.26026e+07 28738.6 1.37667e+07 4834.99 1.21939e+07 6414.89 9.16235e+07 3392.58 1.75247e+08 22866.7 1.74367e+07 29313 1.7961e+07 3800.32 1.45532e+07 2044.67 1.14074e+07 1410.46 7.73741e+06 1.33856e+06 3.59298e+07

images

@@ -59,6 +61,13 @@ extern "C"
}
#endif

// Host and enclave versions must match. Otherwise the node may crash much
// later (e.g. unhandled ring buffer message on either end)
if (std::string(host_version) != ccf::ccf_version)
Copy link
Contributor

@ashamis ashamis May 3, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I might be missing something here but the comment in the PR says you compare commits but this is comparing versions. Not that I think there is any issue with comparing either one.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point. The ccf::ccf_version is retrieved from common/version.h which is generated by cmake based on the long version string which is derived by git describe --tags, and changes for every commit (e.g. "ccf-1.0.0-rc1-40-ge1d549c04" for my current local checkout). So yeah, it's referred to as version because it will be a nice and neat version for major releases (e.g. ccf-1.0.0) but is more specific for everything in between.

@jumaffre jumaffre marked this pull request as draft May 4, 2021 13:16
@jumaffre jumaffre marked this pull request as ready for review May 5, 2021 16:33
NodeAlreadyCreated = 2,
VersionMismatch = 3,
ConsensusNotAllowed = 4,
TooManyThreads = 5,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MoreThreadsThanTCSCount would be a little more precise here

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems to be hardcoded to 24 in our code base, independently of the oe_sign.conf NumTCS. Am I missing something?

#include "ds/json.h"
#include "ds/logger.h"
#include "ds/spin_lock.h"
#include "ds/stacktrace_utils.h"
#include "enclave.h"
#include "enclave_time.h"
#include "oe_shim.h"
#include "version.h"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a note, but don't think its actually a problem at the moment.

Most of our directory-less includes are in the same directory as the current file. This is an exception, since its in build/generated. This is not installed, so is not visible to an app. Its unclear that this is different and may confuse us when it breaks in future - perhaps we should put these all under build/_gen/generated, so we can call them generated/version.h here (but keeping an extra layer so we're adding build/_gen to the include dirs, not build/).

This won't break at the moment because apps don't actually build this file (its built into libccf, and they link to that). But now that it looks like we have a ccf_version that can be used within the enclave, its probably only a matter of time before we try to use that in an app, and find that the include is surprisingly unavailable.

I'm not sure what we'd do to fix this. Maybe I'm saying version.h should be put under include/ccf as a public header, even though its generated?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This a very good point, I think distributing version.h as a public include is an excellent idea.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See #2562

@eddyashton
Copy link
Member

I think a check on the host would be more natural than a check in the enclave. If we ever want to use mixed versions, I think this will always be a newer host trying to talk to an older enclave (ie - the host is cheaper to rebuild and redeploy than the enclave, so if we can patch just the host that's preferable). If the enclave is checking versions, this new host needs to impersonate an old host, and potentially different old host-versions depending on which enclave its talking to. If the host did the check, this could be more naturally expressed in the host code ("I'm 2.4.5, but I know I can still talk to an enclave on 2.4.3 or 2.4.4").

RE: Dealing with out-strings - I think we just create a big-enough buffer (say 128 chars), and give the enclave an out-ptr and size as we do for certs.

@jumaffre
Copy link
Contributor Author

jumaffre commented May 6, 2021

I think a check on the host would be more natural than a check in the enclave. If we ever want to use mixed versions, I think this will always be a newer host trying to talk to an older enclave (ie - the host is cheaper to rebuild and redeploy than the enclave, so if we can patch just the host that's preferable). If the enclave is checking versions, this new host needs to impersonate an old host, and potentially different old host-versions depending on which enclave its talking to. If the host did the check, this could be more naturally expressed in the host code ("I'm 2.4.5, but I know I can still talk to an enclave on 2.4.3 or 2.4.4").

RE: Dealing with out-strings - I think we just create a big-enough buffer (say 128 chars), and give the enclave an out-ptr and size as we do for certs.

Good point. This is what I initially intended but the idea somehow got lost along the way. This is now done.

@achamayou achamayou merged commit f5d6502 into microsoft:main May 6, 2021
jumaffre added a commit to jumaffre/CCF that referenced this pull request Oct 22, 2021
achamayou pushed a commit that referenced this pull request Oct 22, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Enclave-host compatibility check
5 participants