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

Add certify example #521

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

Firstyear
Copy link
Contributor

This shows how to make an AIK that has been endorsed and is used to certify other objects.

@Firstyear
Copy link
Contributor Author

Okay, I've updated this with many thanks to @ionut-arm for teaching me about how this works. It seems to be working BUT I think this is highlighting a bug in this library.

I think we aren't cleaning up sessions properly.

This example fails with:

WARNING:esys:src/tss2-esys/api/Esys_StartAuthSession.c:391:Esys_StartAuthSession_Finish() Received TPM Error
ERROR:esys:src/tss2-esys/api/Esys_StartAuthSession.c:136:Esys_StartAuthSession() Esys Finish ErrorCode (0x00000903)
[2024-04-12T05:58:48Z ERROR tss_esapi::context::tpm_commands::session_commands] Error when creating a session: 0x00000903
thread 'main' panicked at tss-esapi/examples/certify.rs:348:10:
Invalid session attributes.: TssError(Tpm(FormatZero(Warning(TpmFormatZeroWarningResponseCode { error_number: SessionMemory }))))

Thing is, if we look at those lines:

https://github.com/parallaxsecond/rust-tss-esapi/pull/521/files#diff-d5e5d81654fd33f9a61e28fad7ac81325147e0e488198cc2b7ae84babc000e21R308

We clear sessions just before, then we run out of session memory.

I have recently been noticing a lot of issues with x0901 errors in the kernel due to session memory, and so I am led to think we have a bug somewhere in how we flush and handle sessions.

@Firstyear Firstyear marked this pull request as draft April 12, 2024 06:01
@ionut-arm
Copy link
Member

Indeed, you seem to be calling clear_sessions and expecting them to be wiped from the TPM, but what actually happens is that the Context simply forgets about those sessions. At the end they're still in the TPM, and we've lost the handles for them.

Given that AuthSession is Copy and Clone, I don't think it's wise for us to implement Drop on them (and tbh that would require the sessions to carry an extra reference to Context). My suggestion would be: improve the docs around clear_session to make it clear that the sessions remain in the TPM; add a new method (maybe purge_sessions? or flush_sessions?) that flushes them from the TPM and then clears them from the context memory. Does that sound sensible?

@Firstyear
Copy link
Contributor Author

You could give the AuthSession an inner Arc that has Drop instead?

But yes alternately we need flush_sessions or similar. :)

@ionut-arm
Copy link
Member

You could give the AuthSession an inner Arc that has Drop instead?

The problem with that is the cascade effects to the interface: since you're flushing the session whenever the object gets destoyed, you can't have it implement Copy or Clone anymore. That means that every function which expects an AuthSession must be switched to &AuthSession. You also need to update all conversions, for example from AuthSession to PolicySession, because destructuring a Drop-able object is not allowed. It turns into a pretty big effort.

If you'd like to do this please go ahead! My suggestion was primarily based on expected change size. :)

@Firstyear
Copy link
Contributor Author

You could give the AuthSession an inner Arc that has Drop instead?

The problem with that is the cascade effects to the interface: since you're flushing the session whenever the object gets destoyed, you can't have it implement Copy or Clone anymore.

Well you can have Clone because you can use Arc/Rc. Probably Rc in this case, because I think these are not really thread safe objects at all.

That means that every function which expects an AuthSession must be switched to &AuthSession. You also need to update all conversions, for example from AuthSession to PolicySession, because destructuring a Drop-able object is not allowed. It turns into a pretty big effort.

If you'd like to do this please go ahead! My suggestion was primarily based on expected change size. :)

Well, changing to have an inner that handles things with an Rc is fine, but the question here is do we actually have the apis exposed to flush a session so we can write the drop handler?

@ionut-arm
Copy link
Member

ionut-arm commented Apr 24, 2024

Sorry, I should've been clearer! What I meant about Clone and Copy is that if you have multiple clones of the same session and you have "flush on Drop" for them, then the moment your first clone goes out of scope it will make the others unusable. So you might as well not allow cloning, as it'll lead to weird errors that seem to come out of nowhere.

do we actually have the apis exposed to flush a session so we can write the drop handler?

Of course, here's an example.

@Firstyear
Copy link
Contributor Author

To help explain I'm suggesting we have:

AuthSession {
    inner: Rc<AuthSessionInner>
}

AuthSessionInner {
    handle: ....
}

impl Drop for AuthSessionInner {
    fn drop (&mut self) {
        // whatever we need to do to flush the session.
    }
}

That way the outher AuthSession is still copy/clone, but then when it's dropped we can still auto-flush.

@ionut-arm
Copy link
Member

Ah, I see! Yes, that'll work, though Arc is probably preferable since multithreading shouldn't be discounted. I think sessions can be seen as immutable, so you don't have to worry about that either.

There might be some other issues that I'm not foreseeing, but hopefully implementable if you want to give it a go.

@Firstyear
Copy link
Contributor Author

Ah, I see! Yes, that'll work, though Arc is probably preferable since multithreading shouldn't be discounted. I think sessions can be seen as immutable, so you don't have to worry about that either.

There might be some other issues that I'm not foreseeing, but hopefully implementable if you want to give it a go.

I think the main issue I'd forsee is the whole API currently still relies on a fair bit of manual memory management anyway. So having some types that auto-free and some that don't could be confusing.

Anyway, for now I updated the example with a manual drop of the session and it passes!

But eventually if you run these in a loop, duplication, duplication secret and certify all end up leaking memory and causing the TPM RM to lockup. I'm not 100% sure why, I can't find what I'm "not freeing".

These are the first examples that use Policy Sessions, so could it by that I need to free those also?

@Firstyear Firstyear marked this pull request as ready for review April 25, 2024 02:14
@Firstyear
Copy link
Contributor Author

@ionut-arm Anyway, separate to me fixing session handling, I think a pre-lim review of this would be great then I'll get it sorted for merge by squashing and fixing the commit messages. Is that okay/

@ionut-arm
Copy link
Member

@ionut-arm Anyway, separate to me fixing session handling, I think a pre-lim review of this would be great then I'll get it sorted for merge by squashing and fixing the commit messages. Is that okay/

Yes, apologies for the delay. Staying on top of things has been challenging as of late, will add this to my TODO stack, I'll hopefully get to it today or tomorrow!

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.

None yet

2 participants