Received: by 2002:a25:6193:0:0:0:0:0 with SMTP id v141csp1222993ybb; Fri, 20 Mar 2020 15:58:53 -0700 (PDT) X-Google-Smtp-Source: ADFU+vvlWBEnf2eOpMdgexLJK45qi6YypzlHdXkx0yoKw9Mjgb9sZwVQx3keu/VsUS4eddkkaPNF X-Received: by 2002:a05:6830:1bc9:: with SMTP id v9mr8623508ota.319.1584745133273; Fri, 20 Mar 2020 15:58:53 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1584745133; cv=none; d=google.com; s=arc-20160816; b=VM7iO3+j8w1npjC+BV4y6fE3SH5+JbZFeOkhxi/j/O5QwZuNiMJABa6B27C5at54d8 vTAbmFu9ma2kQMT5xfzL6cUMqR2issVQiO9N/8SJWBsW6CLv9hfurRUntfkMpveRX9SF Wvy09dh1q3XJ27yfJVCZsY4x/++Bzwg//iqePPm4t2Ku5jjspzcXUTI6PSsiGVKwn5RN oQOIZ5CAUBqFAqxDEJzoqpi5leOduI5MXkp2RPAzeD55/M2SQv632HhDzGSAEFtBiyQX xesvZ7sc7aEswQRm64MCZw6rzl1qVnd5pjEXEtZOpaP3/r7A4sMhGx6yqqHsVeznvtYg eMtw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:in-reply-to:content-transfer-encoding :content-disposition:mime-version:references:message-id:subject:cc :to:from:date:dkim-signature; bh=UNjVT/x9G5I9C0c9EGviEToxc1QrdxoKplmLqUKbfGo=; b=pJo+TcVjw25ZoYZvOTyHv108Q9APOwWDUKh+6qkSI2N2PSjCqn+zI410fIgxgNjzms 5+BJ+0aaC8XN79rdMkJfCu6cBtb/nxGNWm3ozSu2HQkRuorvuz7UunATzbJFAOEkPkws jPNFdNsV8JgL1h9gg1ZyjpGxKvWnq89sKCuc00ldUubYluKx2EiIdWKBEF4SA9HTL80/ 8t5bCqkugdXOhZ2jTkkiDGQ8H8D79XXR6fvfKGvA32/MBzOlUneC8cdwkpsb/eD1AwNa vKgxB5Ji82xwiiKKWo55KL3ojqSowQJaZzxyDWXbstPDX10952B8yzEEfbGBQJutT438 pVpg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=faT5+QYL; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id g81si3380939oia.8.2020.03.20.15.58.41; Fri, 20 Mar 2020 15:58:53 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=faT5+QYL; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727411AbgCTW6O (ORCPT + 99 others); Fri, 20 Mar 2020 18:58:14 -0400 Received: from us-smtp-delivery-74.mimecast.com ([216.205.24.74]:20011 "EHLO us-smtp-delivery-74.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726997AbgCTW6O (ORCPT ); Fri, 20 Mar 2020 18:58:14 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1584745092; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=UNjVT/x9G5I9C0c9EGviEToxc1QrdxoKplmLqUKbfGo=; b=faT5+QYLoFQIiCZMDOh88wPvdsh6xUbhEZni4+S5wrwn94efKJKdF1777di1gBRWbU6uaO /Leoes5Uu8lDd9naEUFB65cwOYUNkgtx4MMdUM8Pa8lD0jngsf18zXL1b6rkeqqHD3VbY/ SUS/IXTJtuKKh9wFyOi95hLSAgvvwFM= Received: from mail-wr1-f70.google.com (mail-wr1-f70.google.com [209.85.221.70]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-205-aI_jMZiZMiqjRgqMR-AEuA-1; Fri, 20 Mar 2020 18:58:10 -0400 X-MC-Unique: aI_jMZiZMiqjRgqMR-AEuA-1 Received: by mail-wr1-f70.google.com with SMTP id u12so3357447wrw.10 for ; Fri, 20 Mar 2020 15:58:10 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:content-transfer-encoding :in-reply-to; bh=UNjVT/x9G5I9C0c9EGviEToxc1QrdxoKplmLqUKbfGo=; b=t0+wUrZFeoyEzIVXG5O1YUbAYoukX/Obb0gK9Y5srst4ohWlAjoLfjI01xcrh2AGGP ejMJ6Ykbl8neyDhE9rjA1Q/NlJpnmX79fjfQYBwUut8hlHlYsjtSrR/ghBf8Ht9zwSkM +WP8PUdjCaBVNnKm7P1wNBE05ua3HQtyw8X8ByHccs1wmEwEpv6SvS3UbLVrzndl8qVP KJmZtg71WKmxpJYQH73mwNjRDyPV5XZTnDC/MeBLjRCExYICmHo/nhN6+YAdc8seIuVd IIEy1JhWSENe5hoS24iloHC6ZFiVVsV0nisO6lhqZme7v087Ze0K1RLUTnM6H5VlKfag hDOA== X-Gm-Message-State: ANhLgQ04tK4obp1Qv1/pfJSgTJBUGdWR9sQYwIxQ+LbfA2Rl1qDm9w4o cv7RiKgbPOyq9E4xoHPwYe+YxIENaJI5EOhmmetXZmY9PNEOAgqqBJjWguzc6LWeNS4Cll3kPv7 Z5ySt8OudLNduHIDW3zC/5G+p X-Received: by 2002:a7b:cc8a:: with SMTP id p10mr12696825wma.10.1584745089250; Fri, 20 Mar 2020 15:58:09 -0700 (PDT) X-Received: by 2002:a7b:cc8a:: with SMTP id p10mr12696772wma.10.1584745088240; Fri, 20 Mar 2020 15:58:08 -0700 (PDT) Received: from xz-x1 ([2607:9880:19c0:32::2]) by smtp.gmail.com with ESMTPSA id z188sm7594238wme.46.2020.03.20.15.58.05 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 20 Mar 2020 15:58:07 -0700 (PDT) Date: Fri, 20 Mar 2020 18:58:02 -0400 From: Peter Xu To: Sean Christopherson Cc: Christian Borntraeger , Janosch Frank , Paolo Bonzini , David Hildenbrand , Cornelia Huck , kvm@vger.kernel.org, linux-kernel@vger.kernel.org, Qian Cai Subject: Re: [PATCH 1/7] KVM: Fix out of range accesses to memslots Message-ID: <20200320225802.GH127076@xz-x1> References: <20200320205546.2396-1-sean.j.christopherson@intel.com> <20200320205546.2396-2-sean.j.christopherson@intel.com> <20200320221708.GF127076@xz-x1> <20200320224041.GB3866@linux.intel.com> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: <20200320224041.GB3866@linux.intel.com> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Fri, Mar 20, 2020 at 03:40:41PM -0700, Sean Christopherson wrote: > On Fri, Mar 20, 2020 at 06:17:08PM -0400, Peter Xu wrote: > > On Fri, Mar 20, 2020 at 01:55:40PM -0700, Sean Christopherson wrote: > > > Reset the LRU slot if it becomes invalid when deleting a memslot to fix > > > an out-of-bounds/use-after-free access when searching through memslots. > > > > > > Explicitly check for there being no used slots in search_memslots(), and > > > in the caller of s390's approximation variant. > > > > > > Fixes: 36947254e5f9 ("KVM: Dynamically size memslot array based on number of used slots") > > > Reported-by: Qian Cai > > > Cc: Peter Xu > > > Signed-off-by: Sean Christopherson > > > --- > > > arch/s390/kvm/kvm-s390.c | 3 +++ > > > include/linux/kvm_host.h | 3 +++ > > > virt/kvm/kvm_main.c | 3 +++ > > > 3 files changed, 9 insertions(+) > > > > > > diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c > > > index 807ed6d722dd..cb15fdda1fee 100644 > > > --- a/arch/s390/kvm/kvm-s390.c > > > +++ b/arch/s390/kvm/kvm-s390.c > > > @@ -2002,6 +2002,9 @@ static int kvm_s390_get_cmma(struct kvm *kvm, struct kvm_s390_cmma_log *args, > > > struct kvm_memslots *slots = kvm_memslots(kvm); > > > struct kvm_memory_slot *ms; > > > > > > + if (unlikely(!slots->used_slots)) > > > + return 0; > > > + > > > cur_gfn = kvm_s390_next_dirty_cmma(slots, args->start_gfn); > > > ms = gfn_to_memslot(kvm, cur_gfn); > > > args->count = 0; > > > diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h > > > index 35bc52e187a2..b19dee4ed7d9 100644 > > > --- a/include/linux/kvm_host.h > > > +++ b/include/linux/kvm_host.h > > > @@ -1032,6 +1032,9 @@ search_memslots(struct kvm_memslots *slots, gfn_t gfn) > > > int slot = atomic_read(&slots->lru_slot); > > > struct kvm_memory_slot *memslots = slots->memslots; > > > > > > + if (unlikely(!slots->used_slots)) > > > + return NULL; > > > + > > > if (gfn >= memslots[slot].base_gfn && > > > gfn < memslots[slot].base_gfn + memslots[slot].npages) > > > return &memslots[slot]; > > > diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c > > > index 28eae681859f..f744bc603c53 100644 > > > --- a/virt/kvm/kvm_main.c > > > +++ b/virt/kvm/kvm_main.c > > > @@ -882,6 +882,9 @@ static inline void kvm_memslot_delete(struct kvm_memslots *slots, > > > > > > slots->used_slots--; > > > > > > + if (atomic_read(&slots->lru_slot) >= slots->used_slots) > > > + atomic_set(&slots->lru_slot, 0); > > > > Nit: could we drop the atomic ops? The "slots" is still only used in > > the current thread before the rcu assignment, so iirc it's fine (and > > RCU assignment should have a mem barrier when needed anyway). > > No, atomic_t wraps an int inside a struct to prevent direct usage, e.g. > > virt/kvm/kvm_main.c: In function ‘kvm_memslot_delete’: > virt/kvm/kvm_main.c:885:22: error: invalid operands to binary >= (have ‘atomic_t {aka struct }’ and ‘int’) > if (slots->lru_slot >= slots->used_slots) > ^ > virt/kvm/kvm_main.c:886:19: error: incompatible types when assigning to type ‘atomic_t {aka struct }’ from type ‘int’ > slots->lru_slot = 0; > > > Buy yeah, the compiler barrier associated with atomic_read() isn't > necessary. Oops, sorry. I was obviously thinking about QEMU's atomic helpers. > > > I thought resetting lru_slot to zero would be good enough when > > duplicating the slots... however if we want to do finer grained reset, > > maybe even better to reset also those invalidated ones (since we know > > this information)? > > > > if (slots->lru_slot >= slots->id_to_index[memslot->id]) > > slots->lru_slot = 0; > > I'd prefer to go with the more obviously correct version. This code will > rarely trigger, e.g. larger slots have lower indices and are more likely to > be the LRU (by virtue of being the biggest), and dynamic memslot deletion > is usually for relatively small ranges that are being remapped by the guest. IMHO the more obvious correct version could be unconditionally setting lru_slot to something invalid (e.g. -1) in kvm_dup_memslots(), then in the two search_memslots() skip the cache if lru_slot is invalid. That's IMHO easier to understand than the "!slots->used_slots" checks. But I've no strong opinion. Thanks, -- Peter Xu