confidential-containers / td-shim

Confidential Containers Shim Firmware
Other
97 stars 53 forks source link

Can TD-Shim skip relocations for the ELF payload? #420

Open dimakuv opened 2 years ago

dimakuv commented 2 years ago

I am developing my ELF payload that TD-Shim loads.

My ELF payload is a generic OS kernel that can be started in different ways. One of these ways is as an ELF payload via the TD-Shim.

Therefore, my ELF payload has a generic startup sequence that has the step of self-relocation. In other words, one of the first things my ELF payload does is to find all relocations (by reading its own ELF header and metadata) and apply them.

I am confused by the TD-Shim linker logic:

Maybe I don't understand the difference between payload and ipl? Is there a way to skip relocations of my ELF payload?

gaojiaqi7 commented 2 years ago

td-shim relocates the payload at runtime unconditionally. We can add a feature flag to disable the relocation at runtime

dimakuv commented 2 years ago

@gaojiaqi7 Thanks for reply. Yes, adding such a flag would be nice.

gaojiaqi7 commented 2 years ago

hi @dimakuv Can you take a try with the https://github.com/confidential-containers/td-shim/pull/424 so that I can make sure the change is good

dimakuv commented 2 years ago

Thanks @gaojiaqi7! I'll try this PR tomorrow.

dimakuv commented 2 years ago

@gaojiaqi7 Got this error after updating to your #424 branch:

$ cargo run -p td-shim-tools --features="linker" --no-default-features \
    --bin td-shim-ld -- \
    target/x86_64-unknown-uefi/release/ResetVector.bin \
    target/x86_64-unknown-uefi/release/td-shim.efi \
    -p <my ELF payload> \
    -o target/x86_64-unknown-uefi/release/final-elf.bin

    ...
   Compiling td-shim v0.1.0 (/home/dimakuv/td-shim/td-shim)
   Compiling td-shim-tools v0.1.0 (/home/dimakuv/td-shim/td-shim-tools)
    Finished dev [unoptimized + debuginfo] target(s) in 1.01s
     Running `target/debug/td-shim-ld target/x86_64-unknown-uefi/release/ResetVector.bin target/x86_64-unknown-uefi/release/td-shim.efi -p <my ELF payload> -o target/x86_64-unknown-uefi/release/final-elf.bin`
Error: Custom { kind: Other, error: "Can not relocate IPL content" }

Note that I didn't yet apply the disable-relocation feature (wanted to test without this flag first). What could this mean?

gaojiaqi7 commented 2 years ago

I can't reproduce this error with the example td-payload. Can you try to recompile the td-shim? we changed its target has to x86_64-unknown-none recently

dimakuv commented 2 years ago

Ok, a clean rebuild fixed this issue.

My payload works fine without the disable-relocation feature (so, with defaults). For this to work, I modified my payload to not perform relocations by itself.

But when I tried --features="disable-relocation" and with my payload unmodified, everything started silently failing. (I will need to debug this tomorrow, just giving you a quick reply now.)

I have a stupid question: where do I need to add this feature? Here's roughly how I tested:

git clone https://github.com/gaojiaqi7/td-shim.git
git checkout td-loader --

git submodule update --init --recursive
 ./sh_script/preparation.sh

cargo xbuild -p td-shim --target x86_64-unknown-none --release --features=main,tdx,disable-relocation --no-default-features

cargo run -p td-shim-tools --features="linker" --no-default-features --bin td-shim-ld -- \
    target/x86_64-unknown-none/release/ResetVector.bin \
    target/x86_64-unknown-none/release/td-shim \
    -p <my ELF payload> \
    -o target/x86_64-unknown-none/release/final.bin

Is this sequence correct?

gaojiaqi7 commented 2 years ago

Yes, it is correct. The feature is set to td-shim

gaojiaqi7 commented 2 years ago

Therefore, my ELF payload has a generic startup sequence that has the step of self-relocation. In other words, one of the first things my ELF payload does is to find all relocations (by reading its own ELF header and metadata) and apply them.

@dimakuv how does your ELF payload read its own ELF header and metadata, using offset or something else? Dose the payload needs loader to map its segments to the specified virtual address?

dimakuv commented 2 years ago

@gaojiaqi7 The ELF payload reads its own ELF header and metadata using a global symbol that is located at the very start of the ELF file image (and thus points to the ELF header).

Similar to this code:

There is no need for the loader to map the segments to the specific virtual address. The address can be anything.

gaojiaqi7 commented 2 years ago

Hi @dimakuv I updated the branch today, can you try again with the latest?

dimakuv commented 2 years ago

@gaojiaqi7 No, still the same problem. And I still didn't have time to debug it fully.