All of lore.kernel.org
 help / color / mirror / Atom feed
* KVM_MEM_READONLY slot flag not working properly
@ 2021-03-18 11:28 Lorenzo Susini
  2021-03-18 16:07 ` Laszlo Ersek
  0 siblings, 1 reply; 5+ messages in thread
From: Lorenzo Susini @ 2021-03-18 11:28 UTC (permalink / raw)
  To: qemu-devel

[-- Attachment #1: Type: text/plain, Size: 1480 bytes --]

Hello,

Have some of you successfully used the KVM_MEM_READONLY slot flag?

I'm working on a project and I'm trying to protect the guest's IDT by using
KVM, modifying kvm-all.c.
I'm able to correctly locate the IDT in the host by reading IDTR with
KVM_GET_SREGS,
translating it with KVM_TRANSLATE and, by using the KVMSlot struct, I'm
able to find the corresponding
host virtual address. I've double checked the addresses with the Qemu
Monitor (gpa2hva and gva2gpa) and they
are correct.

Then, I decided to split the slot where the IDT currently lives into three
separate ones, setting the IDT in its own private slot and making it
read-only with KVM_MEM_READONLY:

INITIAL SLOT ===> PRE IDT SLOT |  IDT SLOT (KVM_MEM_READONLY)  |  POST IDT
SLOT.

By doing this, the VM continues its execution normally. Also, I'm not
moving memory in the host when
reassigning slots, so I'm just changing the sizes and the addresses when
doing kvm_set_userspace_memory_region,
there's no need to move data anywhere else in my opinion, and this is
confirmed by the fact that VM, after doing so, behaves normally.

However, when I try to register a new interrupt handler (for instance for
the edu device, just to try it out), it works perfectly,
meaning that the IDT is not really read-only. Do you have any idea why? Any
suggestions on how to solve the problem?
Of course I've also checked KVM_CAP_READONLY_MEM, no problem with that.

Anyway, is this the right place to post?

Thank you,
Lorenzo

[-- Attachment #2: Type: text/html, Size: 1873 bytes --]

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: KVM_MEM_READONLY slot flag not working properly
  2021-03-18 11:28 KVM_MEM_READONLY slot flag not working properly Lorenzo Susini
@ 2021-03-18 16:07 ` Laszlo Ersek
  2021-03-18 17:04   ` Paolo Bonzini
  0 siblings, 1 reply; 5+ messages in thread
From: Laszlo Ersek @ 2021-03-18 16:07 UTC (permalink / raw)
  To: Lorenzo Susini, qemu-devel
  Cc: Paolo Bonzini, Vitaly Kuznetsov, Philippe Mathieu-Daudé, Peter Xu

On 03/18/21 12:28, Lorenzo Susini wrote:
> Hello,
> 
> Have some of you successfully used the KVM_MEM_READONLY slot flag?

I think the operation of the pflash device is based on that, yes.

One related commit is 235e8982ad39 ("kvm: support using KVM_MEM_READONLY
flag for regions", 2013-05-29).

So in pflash, there are memory_region_rom_device_set_romd() calls.

When the argument is false (readonly=false, rom_device=true,
*romd_mode=false*), the KVM memory slot is removed completely
(kvm_set_phys_mem()), and all accesses trap to QEMU (work as MMIO).

When the argument is true (readonly=false, rom_device=true,
*romd_mode=true*), a read-only memory slot is used, read/exec doesn't
trap, writes do (kvm_mem_flags(), memory_region_is_romd()).

I've copied Paolo, Vitaly, Peter and Phil.

Thanks
Laszlo

> 
> I'm working on a project and I'm trying to protect the guest's IDT by using
> KVM, modifying kvm-all.c.
> I'm able to correctly locate the IDT in the host by reading IDTR with
> KVM_GET_SREGS,
> translating it with KVM_TRANSLATE and, by using the KVMSlot struct, I'm
> able to find the corresponding
> host virtual address. I've double checked the addresses with the Qemu
> Monitor (gpa2hva and gva2gpa) and they
> are correct.
> 
> Then, I decided to split the slot where the IDT currently lives into three
> separate ones, setting the IDT in its own private slot and making it
> read-only with KVM_MEM_READONLY:
> 
> INITIAL SLOT ===> PRE IDT SLOT |  IDT SLOT (KVM_MEM_READONLY)  |  POST IDT
> SLOT.
> 
> By doing this, the VM continues its execution normally. Also, I'm not
> moving memory in the host when
> reassigning slots, so I'm just changing the sizes and the addresses when
> doing kvm_set_userspace_memory_region,
> there's no need to move data anywhere else in my opinion, and this is
> confirmed by the fact that VM, after doing so, behaves normally.
> 
> However, when I try to register a new interrupt handler (for instance for
> the edu device, just to try it out), it works perfectly,
> meaning that the IDT is not really read-only. Do you have any idea why? Any
> suggestions on how to solve the problem?
> Of course I've also checked KVM_CAP_READONLY_MEM, no problem with that.
> 
> Anyway, is this the right place to post?
> 
> Thank you,
> Lorenzo
> 



^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: KVM_MEM_READONLY slot flag not working properly
  2021-03-18 16:07 ` Laszlo Ersek
@ 2021-03-18 17:04   ` Paolo Bonzini
  2021-03-18 17:40     ` Lorenzo Susini
  0 siblings, 1 reply; 5+ messages in thread
From: Paolo Bonzini @ 2021-03-18 17:04 UTC (permalink / raw)
  To: Laszlo Ersek, Lorenzo Susini, qemu-devel
  Cc: Vitaly Kuznetsov, Philippe Mathieu-Daudé, Peter Xu

On 18/03/21 17:07, Laszlo Ersek wrote:
> However, when I try to register a new interrupt handler (for instance for
> the edu device, just to try it out), it works perfectly,
> meaning that the IDT is not really read-only. Do you have any idea why? Any
> suggestions on how to solve the problem?
> Of course I've also checked KVM_CAP_READONLY_MEM, no problem with that.

Sorry for asking a question that might be extremely stupid, but: did you 
check that the guest is writing to the IDT?  For example Linux never 
modifies the IDT when it runs, in fact it even makes it read only (check 
out idt_setup_apic_and_irq_gates in arch/x86/kernel/idt.c).

Paolo



^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: KVM_MEM_READONLY slot flag not working properly
  2021-03-18 17:04   ` Paolo Bonzini
@ 2021-03-18 17:40     ` Lorenzo Susini
  2021-03-18 17:54       ` Paolo Bonzini
  0 siblings, 1 reply; 5+ messages in thread
From: Lorenzo Susini @ 2021-03-18 17:40 UTC (permalink / raw)
  To: Paolo Bonzini
  Cc: Philippe Mathieu-Daudé,
	Vitaly Kuznetsov, Laszlo Ersek, qemu-devel, Peter Xu

[-- Attachment #1: Type: text/plain, Size: 1310 bytes --]

Well I'm sorry but I didn't know IDT was marked as read only by Linux. If
it is read only, how can you
register any new interrupt handler? I guess it's a way of securing stuff
against malicious attacks.
I was taking for granted that the IDT was written when registering a new
irq handler,
given that when an interrupt is raised, the new specified handler has to be
called
and its address should be retrieved in some way, that is by storing it in
the IDT.

I'm sorry, I'm a student and I'm trying to understand things,
Thank you,
Lorenzo

Il giorno gio 18 mar 2021 alle ore 18:04 Paolo Bonzini <pbonzini@redhat.com>
ha scritto:

> On 18/03/21 17:07, Laszlo Ersek wrote:
> > However, when I try to register a new interrupt handler (for instance for
> > the edu device, just to try it out), it works perfectly,
> > meaning that the IDT is not really read-only. Do you have any idea why?
> Any
> > suggestions on how to solve the problem?
> > Of course I've also checked KVM_CAP_READONLY_MEM, no problem with that.
>
> Sorry for asking a question that might be extremely stupid, but: did you
> check that the guest is writing to the IDT?  For example Linux never
> modifies the IDT when it runs, in fact it even makes it read only (check
> out idt_setup_apic_and_irq_gates in arch/x86/kernel/idt.c).
>
> Paolo
>
>

[-- Attachment #2: Type: text/html, Size: 1790 bytes --]

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: KVM_MEM_READONLY slot flag not working properly
  2021-03-18 17:40     ` Lorenzo Susini
@ 2021-03-18 17:54       ` Paolo Bonzini
  0 siblings, 0 replies; 5+ messages in thread
From: Paolo Bonzini @ 2021-03-18 17:54 UTC (permalink / raw)
  To: Lorenzo Susini
  Cc: Laszlo Ersek, Vitaly Kuznetsov, Philippe Mathieu-Daudé,
	qemu-devel, Peter Xu

On 18/03/21 18:40, Lorenzo Susini wrote:
> Well I'm sorry but I didn't know IDT was marked as read only by
> Linux. If it is read only, how can you register any new interrupt
> handler? I guess it's a way of securing stuff against malicious
> attacks. I was taking for granted that the IDT was written when
> registering a new irq handler, given that when an interrupt is
> raised, the new specified handler has to be called and its address
> should be retrieved in some way, that is by storing it in the IDT.

There's a list of handlers for each IDT entry.  This is because the  IDT 
entrypoint has to do more stuff before and after calling the function 
(and also it has to return with IRET instead of RET).  So the IDT entry 
does not point directly to the function that you register.

(Also some interrupts may be shared by multiple devices, in which case 
you can have more than one handler).

> I'm sorry, I'm a student and I'm trying to understand things, Thank
> you, Lorenzo

No problem. :)

Paolo



^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2021-03-18 18:27 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-03-18 11:28 KVM_MEM_READONLY slot flag not working properly Lorenzo Susini
2021-03-18 16:07 ` Laszlo Ersek
2021-03-18 17:04   ` Paolo Bonzini
2021-03-18 17:40     ` Lorenzo Susini
2021-03-18 17:54       ` Paolo Bonzini

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.