Skip to content

Commit dcf96f7

Browse files
frankjaaborntraeger
authored andcommitted
KVM: s390: Limit adapter indicator access to mapped page
While we check the address for errors, we don't seem to check the bit offsets and since they are 32 and 64 bits a lot of memory can be reached indirectly via those offsets. Fixes: 8422359 ("KVM: s390: irq routing for adapter interrupts.") Suggested-by: Claudio Imbrenda <[email protected]> Reviewed-by: Christian Borntraeger <[email protected]> Reviewed-by: Matthew Rosato <[email protected]> Tested-by: Matthew Rosato <[email protected]> Signed-off-by: Janosch Frank <[email protected]> Signed-off-by: Christian Borntraeger <[email protected]>
1 parent b00be77 commit dcf96f7

1 file changed

Lines changed: 12 additions & 0 deletions

File tree

arch/s390/kvm/interrupt.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2724,6 +2724,9 @@ static unsigned long get_ind_bit(__u64 addr, unsigned long bit_nr, bool swap)
27242724

27252725
bit = bit_nr + (addr % PAGE_SIZE) * 8;
27262726

2727+
/* kvm_set_routing_entry() should never allow this to happen */
2728+
WARN_ON_ONCE(bit > (PAGE_SIZE * BITS_PER_BYTE - 1));
2729+
27272730
return swap ? (bit ^ (BITS_PER_LONG - 1)) : bit;
27282731
}
27292732

@@ -2852,6 +2855,7 @@ int kvm_set_routing_entry(struct kvm *kvm,
28522855
struct kvm_kernel_irq_routing_entry *e,
28532856
const struct kvm_irq_routing_entry *ue)
28542857
{
2858+
const struct kvm_irq_routing_s390_adapter *adapter;
28552859
u64 uaddr_s, uaddr_i;
28562860
int idx;
28572861

@@ -2862,6 +2866,14 @@ int kvm_set_routing_entry(struct kvm *kvm,
28622866
return -EINVAL;
28632867
e->set = set_adapter_int;
28642868

2869+
adapter = &ue->u.adapter;
2870+
if (adapter->summary_addr + (adapter->summary_offset / 8) >=
2871+
(adapter->summary_addr & PAGE_MASK) + PAGE_SIZE)
2872+
return -EINVAL;
2873+
if (adapter->ind_addr + (adapter->ind_offset / 8) >=
2874+
(adapter->ind_addr & PAGE_MASK) + PAGE_SIZE)
2875+
return -EINVAL;
2876+
28652877
idx = srcu_read_lock(&kvm->srcu);
28662878
uaddr_s = gpa_to_hva(kvm, ue->u.adapter.summary_addr);
28672879
uaddr_i = gpa_to_hva(kvm, ue->u.adapter.ind_addr);

0 commit comments

Comments
 (0)