Skip to content
This repository has been archived by the owner on Jan 20, 2022. It is now read-only.

[Pal/Linux-SGX] Fix refcounting on open/close of Protected Files #2372

Closed
wants to merge 3 commits into from

Conversation

dimakuv
Copy link
Contributor

@dimakuv dimakuv commented May 12, 2021

Description of the changes

Previously, file_open() and file_close() on a Protected File had weird semnatics: if the same PF was opened twice, there was only one PF context created, but there were several underlying host FDs. Even weirder, the PF context tied itself to the host FD (the very first opened one) using the pointer to this FD: &pal_handle->file.fd.

This resulted in bugs and cumbersome workarounds: the associated PAL handle could be closed and freed by our common PAL code, and the PF context would contain a dangling pointer. And for file_attrquery(), there was a workaround to destroy the PAL context if it seemed to be created only for this attrquery flow (this was based on this pointer-to-pal-handle-fd).

This PR fixes these bugs: the PF context stores the underlying host FD directly, and doesn't open new FDs on subsequent file_open(). So, there is always only one host FD for one PF context. As a side effect, the logic of file_open() and file_close() is refactored.

A new LibOS regression test protected_file is added for GDB debugging because the dedicated fs/ tests are harder to debug.

Fixes #2360.

How to test this PR?

A new test is added. Also, fs/pf-test should succeed.


This change is Reviewable

Previously, `file_open()` and `file_close()` on a Protected File had
weird semnatics: if the same PF was opened twice, there was only one PF
context created, but there were several underlying host FDs. Even
weirder, the PF context tied itself to the host FD (the very first
opened one) using the pointer to this FD: `&pal_handle->file.fd`.
This resulted in bugs and cumbersome workarounds: the associated PAL
handle could be closed and freed by our common PAL code, and the PF
context would contain a dangling pointer. And for `file_attrquery()`,
there was a workaround to destroy the PAL context if it seemed to be
created only for this attrquery flow.

This commit fixes these bugs: the PF context stores the underlying host
FD directly, and doesn't open new FDs on subsequent `file_open()`. So,
there is always only one host FD for one PF context. As a side effect,
the logic of `file_open()` and `file_close()` is refactored.

A new LibOS regression test `protected_file` is added for GDB debugging
because the dedicated `fs/` tests are harder to debug.

Signed-off-by: Dmitrii Kuvaiskii <dmitrii.kuvaiskii@intel.com>
Signed-off-by: Dmitrii Kuvaiskii <dmitrii.kuvaiskii@intel.com>
Copy link
Contributor Author

@dimakuv dimakuv left a comment

Choose a reason for hiding this comment

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

Reviewable status: 0 of 10 files reviewed, all discussions resolved, not enough approvals from maintainers (2 more required), not enough approvals from different teams (1 more required, approved so far: Intel)


Pal/src/host/Linux-SGX/db_files.c, line 613 at r1 (raw file):

    assert(PF_SUCCESS(pfs));

    if (fd_from_attrquery == *(int*)pf_handle) { /* this is a PF opened just for us, close it */

FYI: If you want to understand what was checked here, think of it this way:

  • The first time Graphene opened this PF, it put pf->context.pf_handle = &first_host_fd
  • The second time Graphene opened the same PF, the ``pf->context.pf_handle` is not changed
  • So when we arrive here, we basically check "Was it the first time Graphene opened this PF, just to do attrquery?"

This was super-brittle and led to dangling pointers, as found in #2360.

The new code simply opens the PF again and closes it afterwards. This works because PF has a refcount.


Pal/src/host/Linux-SGX/protected-files/protected_files.h, line 244 at r1 (raw file):

 * \return PF status
 */
pf_status_t pf_set_mode(pf_context_t* pf, pf_file_mode_t mode);

FYI: I had to add these helpers to prevent the case of "two handles try to open the same PF in writable mode" -- this is prohibited by PFS.

Signed-off-by: Dmitrii Kuvaiskii <dmitrii.kuvaiskii@intel.com>
@dimakuv
Copy link
Contributor Author

dimakuv commented May 18, 2021

Jenkins, retest Jenkins-20.04 please (too old, Jenkins doesn't have it in the logs anymore)

@dimakuv
Copy link
Contributor Author

dimakuv commented Sep 9, 2021

This fix is hacky. We need to refactor Protected Files implementation completely.

@dimakuv dimakuv closed this Sep 9, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

SGX protected files possible vulnerability
1 participant