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 suppport for .nvm_data section loading #467

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

Conversation

bboilot-ledger
Copy link

@bboilot-ledger bboilot-ledger commented Mar 25, 2024

In rust apps, an additional section named .nvm_data is created in the provided ELF. This section represents the NVM storage state which is not null by default.
When it's not loaded the rust code panics because it can't find any "valid storage" (https://github.com/LedgerHQ/ledger-device-rust-sdk/blob/610a73b500730b28c0b8c1b556e089a6b102d7c6/ledger_device_sdk/src/nvm.rs#L217-L225).

This PR adds a quick fix to load this section in memory if it exists. What should really be done is loading segments instead of sections (which are used for linking) but there are still things I do not understand at the moment. We could also load the ihex file but this would require to change the way we're running speculos in every project.

To test this PR, you can use the Password Manager Rust App and try to store a new password with the app running in speculos.

Copy link
Contributor

@xchapron-ledger xchapron-ledger 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 we should implement something equivalent to LedgerBlue behavior, which doesn't check for neither .text or .nvm_data section but is more generic, what do you think about it?

@bboilot-ledger
Copy link
Author

I agree with that and I see two options:

  • Parsing the ELF and loading the segments instead of the sections (which are used for linking purpose)
  • Parsing the ihex file and loading the data in memory (where we can reuse ledgerblue ihex parser)

To do this, we would have to:

  • Not load the .text section to 0x40000000 anymore but rather to the segment specified address (i don't even understand how it works since the app ELF is not PIC)
  • Remove RAM relocation emulation (that moves RAM from 0xda7a0000 to 0x50000000)
  • Remove the _install_params loading thing (from what I understand these param aren't normally load in memory and cannot be used even if they are)
  • In the case of the ihex loading, we would have to give to speculos both the ihex and the elf files which can impact Makefiles, scripts and pipelines
    I don't know what impacts these changes could be causing or the reasons behind what was done in the first place.

In both cases we would still need to parse the elf sections to:

  • load the fonts
  • patch the svc calls

But I think that we also want to mimic the BOLOS loader behavior and I have no information about that. So I am unsure if I would be able to do that currently.

@xchapron-ledger
Copy link
Contributor

I agree with that and I see two options:

  • Parsing the ELF and loading the segments instead of the sections (which are used for linking purpose)
  • Parsing the ihex file and loading the data in memory (where we can reuse ledgerblue ihex parser)

I think if there is no major reason to change, we must continue taking the elf as a input, cause this is issued in so many places...

Not load the .text section to 0x40000000 anymore but rather to the segment specified address (i don't even understand how it works since the app ELF is not PIC)

I'm not sure to understand your point?
C App use a custom PIC macro helper to work without the classical PIC mechanism.
And it's important to relocate the .text section as it's was is done in the real device (depending on the location of the app in the device flash). So we should keep this to emulate properly the need for some PIC at some places in the app and SDK code.

Remove RAM relocation emulation (that moves RAM from 0xda7a0000 to 0x50000000)

Again, the RAM relocation is necessary to emulate properly the behavior on device.

Remove the _install_params loading thing (from what I understand these param aren't normally load in memory and cannot be used even if they are)

They are loaded on device memory, and should therefore be present on Speculos so that the emulation is correct.
Not that it's not properly done in Rust app for now, but the C app behavior is the right one as of now.

@bboilot-ledger
Copy link
Author

Thanks for your answers, that gave me few info on what's the loading behavior on a real device.
In this case, I don't know what we can do to avoid playing with the elf sections and support every devices in C and Rust. Also, I have no idea on what's the current LedgerBlue behavior.

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

3 participants