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

Fix the sandbox use case and add a test. #269

Merged
merged 15 commits into from
Jan 11, 2021
Merged

Fix the sandbox use case and add a test. #269

merged 15 commits into from
Jan 11, 2021

Conversation

davidchisnall
Copy link
Collaborator

Summary of changes:

  • Add a new PAL that doesn't allocate memory, which can be used with a
    memory provider that is pre-initialised with a range of memory.
  • Slightly refactor the memory provider class so that it has a narrower
    interface with LargeAlloc and is easier to proxy.
  • Allow the address space manager and the memory provider to be
    initialised with a range of memory.

This may eventually also remove the need for (or, at least, simplify)
the Open Enclave PAL.

Summary of changes:

- Add a new PAL that doesn't allocate memory, which can be used with a
  memory provider that is pre-initialised with a range of memory.
- Slightly refactor the memory provider class so that it has a narrower
  interface with LargeAlloc and is easier to proxy.
- Allow the address space manager and the memory provider to be
  initialised with a range of memory.

This may eventually also remove the need for (or, at least, simplify)
the Open Enclave PAL.
@davidchisnall davidchisnall requested review from nwf, mjp41 and a user January 7, 2021 16:56
@davidchisnall
Copy link
Collaborator Author

This is neccessary for fixing the Verona process isolation code.

Copy link

@rengolin rengolin left a comment

Choose a reason for hiding this comment

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

I'm not entirely familiar with snmalloc or its implementation, so my comments could be misleading. Grain of salt and all.

src/mem/address_space.h Show resolved Hide resolved
const size_t rsize = bits::one_at_bit(SUPERSLAB_BITS) << large_class;
available_large_chunks_in_bytes -= rsize;
}
return 0;
Copy link

Choose a reason for hiding this comment

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

Shouldn't this return p?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yes. I honestly have no idea how this passes any tests as written.

Copy link
Member

Choose a reason for hiding this comment

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

You probably would only detect this if you are tracking address space usage, this will not recycle any chunks (i.e. 1MiB ranges) of memory, So tests that go up and down in usage a lot will leak. Did it pass CI. I would expect a Windows test to fail with OOM with this bug. But on your own machine, probably none of the tests will come close to an issue.

src/test/func/sandbox/sandbox.cc Outdated Show resolved Hide resolved
{
if constexpr (pal_supports<AlignedAllocation, DefaultPal>)
{
return DefaultPal::reserve_aligned<true>(sb_size);
Copy link
Collaborator

Choose a reason for hiding this comment

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

Needs to test that sb_size >= DefaultPal::minimum_alloc_size?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

In theory, yes, but for this test it will be - I don't think we're going to have a PAL that can't allocate 128MiB.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Not all PALs provide minimum_alloc_size. We should probably add that to the concept...

Copy link
Collaborator

Choose a reason for hiding this comment

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

AFAIK minimum_alloc_size is required by AlignedAllocation PALs. Sorry to have left it out of the concept; I can catch that in my next round of miscellany if you don't want to do it here.

Copy link
Member

Choose a reason for hiding this comment

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

Yep, it uses it here:

if constexpr (pal_supports<AlignedAllocation, PAL>)
{
if (size >= PAL::minimum_alloc_size)
return PAL::template reserve_aligned<committed>(size);
}

*/
static constexpr uint64_t pal_features = 0;

static constexpr size_t page_size = ErrorHandler::page_size;
Copy link
Collaborator

Choose a reason for hiding this comment

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

Maybe BasePal since it's not just for error handling?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I didn't want to call it a Pal because we don't forward any of the memory ops to it.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I've modified this to use the Aal's one, so now this just needs to implement the two error-related things.

*/
static std::pair<void*, size_t> reserve_at_least(size_t) noexcept
{
error("Out of memory");
Copy link
Collaborator

Choose a reason for hiding this comment

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

Maybe expand the comment a bit? "This should never be called. The simplest way to achieve that is to use this PAL with a replacement AddressSpaceManager whose reserve() method does not attempt to use its Pal to reserve memory. See test/func/sandbox/sandbox.cc for an example." ?

Is this here because PalConcept requires it to be? If that's the only reason, maybe we should add a PalFeature NoAllocation flag and relax the Concept in that case?

Copy link
Member

@mjp41 mjp41 Jan 7, 2021

Choose a reason for hiding this comment

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

I like that idea of a feature flag for this.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

The ASM still has this code path, it just shouldn't be reached. Currently, snmalloc doesn't handle allocation failures at all, this is how the other PALs handle allocation failure.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I've added a NoAllocation flag and guarded access to the reserve-family functions on it. This function is now gone.

Copy link
Member

Choose a reason for hiding this comment

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

The ASM still has this code path, it just shouldn't be reached. Currently, snmalloc doesn't handle allocation failures at all, this is how the other PALs handle allocation failure.

Returning nullptr should work for allocation failures. We have tests that check for OOM as that is requried behaviour on OE. If there are code paths that cannot handle a null return from the Pal, then that is a problem.

src/mem/address_space.h Show resolved Hide resolved
CMakeLists.txt Outdated Show resolved Hide resolved
template<bool page_aligned = false>
static void zero(void* p, size_t size) noexcept
{
bzero(p, size);
Copy link
Member

Choose a reason for hiding this comment

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

This would need to be overridable/mixinable for OE to be able to reuse this. It would be nice to not increase the code size unnecessarily.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Or the OE version could just implement snmalloc::bzero as a wrapper around oe_memset_s.

src/test/func/sandbox/sandbox.cc Outdated Show resolved Hide resolved
src/test/func/sandbox/sandbox.cc Show resolved Hide resolved
@rengolin
Copy link

rengolin commented Jan 8, 2021

In GCC 8 test:

../src/mem/allocstats.h:199:22: error: array subscript 18446744073709551601 is above array bounds of 'size_t [28]' {aka 'long unsigned int [28]'} [-Werror=array-bounds]
       large_pop_count[sc]++;

Uninitialised?

@davidchisnall
Copy link
Collaborator Author

CI is happy! Thus ends today's game of whack-a-mole.

Copy link
Member

@mjp41 mjp41 left a comment

Choose a reason for hiding this comment

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

LGTM, thanks for all the changes.

@davidchisnall davidchisnall merged commit c33f355 into master Jan 11, 2021
@davidchisnall davidchisnall deleted the fix_sandbox branch January 11, 2021 14:06
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.

4 participants