coconut-svsm / svsm

COCONUT-SVSM
MIT License
122 stars 41 forks source link

Unsound code patterns #359

Open p4zuu opened 6 months ago

p4zuu commented 6 months ago

Here are some unsound code patterns possibly remaining after @Freax13's initial issue #104.

00xc commented 5 months ago
  • [ ] this_cpu_mut is unsound as it allows creating multiple mutable references pointing to the same location.
  • [ ] PerCpu::ghcb shouldn't give out mutable references with a static lifetime. (@00xc currently working on it)

These will be fixed by #372.

  • [ ] load_idt either needs to take a 'static reference or be unsafe. The same applies to load_tss.

The IDT part should be fixed by #366. TSS still not fixed yet.

00xc commented 5 months ago

This will actually be fixed by #387.

Freax13 commented 2 months ago
  • [ ] PageTableRef doesn't have a lifetime associated with it, so there's no guarantee that the contained PageTable pointer is still live when PageTableRef::deref(_mut) dereferences the pointer.

This will be fixed by #443 (though to be fair AFAICT the original issue doesn't exist anymore anyway).

Freax13 commented 2 months ago

This will be fixed by #450.

Freax13 commented 1 month ago

GuestVMExit does not list all VM exit types (and I don't think this would be feasible given that AMD can decide to add new exit types in the future). We use this type in VMSA. If a guest exits with an unsupported exit type, we have UB.

p4zuu commented 1 month ago

GuestVMExit does not list all VM exit types (and I don't think this would be feasible given that AMD can decide to add new exit types in the future). We use this type in VMSA. If a guest exits with an unsupported exit type, we have UB.

Good catch. If I understand the code correctly, the UB can only be triggered in RequestParams::from_vmsa(), right? If we add a check here, it would still be possible to put an undefined value in VMSA::guest_exit_code somewhere else, but at least we could catch a guest-controlled UB

Freax13 commented 1 month ago

GuestVMExit does not list all VM exit types (and I don't think this would be feasible given that AMD can decide to add new exit types in the future). We use this type in VMSA. If a guest exits with an unsupported exit type, we have UB.

Good catch. If I understand the code correctly, the UB can only be triggered in RequestParams::from_vmsa(), right?

It's UB even if we don't access the value.

If we add a check here, it would still be possible to put an undefined value in VMSA::guest_exit_code somewhere else, but at least we could catch a guest-controlled UB

Can you elaborate on how this check would be implemented?

IMHO we should change GuestVMExit to be defined as pub struct GuestVMExit(u64); and add associated constants for the variants e.g. impl GuestVMExit { pub const MC: Self = Self(0x52); }. This is a fairly common compromise between wanting to have properly named variants but also having the flexibility to allow unknown values.

p4zuu commented 1 month ago

IMHO we should change GuestVMExit to be defined as pub struct GuestVMExit(u64); and add associated constants for the variants e.g. impl GuestVMExit { pub const MC: Self = Self(0x52); }. This is a fairly common compromise between wanting to have properly named variants but also having the flexibility to allow unknown values.

Yes you're right. It looks easier to handle unknown values, and allow room for the new exit codes.

p4zuu commented 1 month ago

IMHO we should change GuestVMExit to be defined as pub struct GuestVMExit(u64); and add associated constants for the variants e.g. impl GuestVMExit { pub const MC: Self = Self(0x52); }. This is a fairly common compromise between wanting to have properly named variants but also having the flexibility to allow unknown values.

Do you plan working on implementing this? I can take it if you want

Freax13 commented 1 month ago

IMHO we should change GuestVMExit to be defined as pub struct GuestVMExit(u64); and add associated constants for the variants e.g. impl GuestVMExit { pub const MC: Self = Self(0x52); }. This is a fairly common compromise between wanting to have properly named variants but also having the flexibility to allow unknown values.

Do you plan working on implementing this? I can take it if you want

Feel free, I'm already quite busy.