Received: by 2002:a25:7ec1:0:0:0:0:0 with SMTP id z184csp5927353ybc; Wed, 27 Nov 2019 11:49:21 -0800 (PST) X-Google-Smtp-Source: APXvYqwVXeTHkA8C5bPfC0R8hu3PZzMuw9h3aPYBqlW6RG24IjtUT0hWoJ/2mxHxxc3iRdQWscW5 X-Received: by 2002:aa7:c2cb:: with SMTP id m11mr10082172edp.89.1574884161564; Wed, 27 Nov 2019 11:49:21 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1574884161; cv=none; d=google.com; s=arc-20160816; b=DclFC7xppE30KM0aE1w+jTuLK8sZKjm+ofWgk3LgXlEYDFi60iwyUUr0gu9ysLkAHB EC4DiweU9JR71mKHMzUZTi5egEhJd1UNMVNDiuFUwG7Tys/hvfyrN/VTTFPOsxhXoXyC Vi71lLGU0yM5MPdwm6OVg18Tjfxgz3bBzWfZei9FIRHKdvVnbL/4/uubMGsFapIyZUXF f4RzQiZ+EYLzhPxCzv6KSClBVsNAheJ8PqN7k+LQwFZM1WjHRKyM1WGqxcTll/wO/E6G OEVjAUF0wfp6qsCR2spN85DAlL2tu+woFId4ZCCimES9aTk6HWub7ea2n31SBMbWGOBS mJpw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:user-agent:in-reply-to :content-disposition:mime-version:references:message-id:subject:cc :to:from:date; bh=5WhD2GK/fzqF8dVWI23yqV44Ltk6IqaNDSVkWAQMv2M=; b=cvLEm0dyzPFCDdwzyshR7luXhgLZawkGhe24oC1bb7NibWGTgriLt4FoXDuUWYQ+/d SeZ+8g55m/21+dSDq1NN4aU/m58Y78DK/r1U4I40Fc/KzAdfpSWA1+Pyyi5VKVFbj+Cl rDB1gtU/lm/LmjhvuKNzDdSt0qPq+N25c7F1Tn2WM1Cx5c75dJyt0mdxzVUDi0sVWsl1 1pSzTTUkf6B033Lt2Fc8HnYdbXYW31GH/h2HgYU0uhA7bkfoGtVJ5rBj8AzKBi1mpinH AZhFSBSKWIyhU1GtPQWN4chmZX/p9GC+Gu4Sew4aS/Od9ud5a2EY76uuG+4gZFi3micL MTeQ== ARC-Authentication-Results: i=1; mx.google.com; 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=fail (p=NONE sp=NONE dis=NONE) header.from=intel.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id r7si10080628edm.224.2019.11.27.11.48.54; Wed, 27 Nov 2019 11:49:21 -0800 (PST) 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; 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=fail (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727109AbfK0Tr7 (ORCPT + 99 others); Wed, 27 Nov 2019 14:47:59 -0500 Received: from mga02.intel.com ([134.134.136.20]:54359 "EHLO mga02.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726593AbfK0Tr6 (ORCPT ); Wed, 27 Nov 2019 14:47:58 -0500 X-Amp-Result: UNKNOWN X-Amp-Original-Verdict: FILE UNKNOWN X-Amp-File-Uploaded: False Received: from fmsmga007.fm.intel.com ([10.253.24.52]) by orsmga101.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 27 Nov 2019 11:47:57 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.69,250,1571727600"; d="scan'208";a="206984788" Received: from sjchrist-coffee.jf.intel.com (HELO linux.intel.com) ([10.54.74.41]) by fmsmga007.fm.intel.com with ESMTP; 27 Nov 2019 11:47:57 -0800 Date: Wed, 27 Nov 2019 11:47:57 -0800 From: Sean Christopherson To: Leonardo Bras Cc: Paolo Bonzini , Paul Mackerras , Radim =?utf-8?B?S3LEjW3DocWZ?= , kvm-ppc@vger.kernel.org, kvm@vger.kernel.org, linux-kernel@vger.kernel.org Subject: Re: [PATCH] KVM: Add separate helper for putting borrowed reference to kvm Message-ID: <20191127194757.GI22227@linux.intel.com> References: <20191021225842.23941-1-sean.j.christopherson@intel.com> <20191126171416.GA22233@linux.intel.com> <0009c6c1bb635098fa68cb6db6414634555039fe.camel@linux.ibm.com> <6beeff56-7676-5dfd-a578-1732730f8963@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.5.24 (2015-08-30) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Wed, Nov 27, 2019 at 04:25:55PM -0300, Leonardo Bras wrote: > On Wed, 2019-11-27 at 19:32 +0100, Paolo Bonzini wrote: > > On 27/11/19 19:24, Leonardo Bras wrote: > > > By what I could undestand up to now, these functions that use borrowed > > > references can only be called while the reference (file descriptor) > > > exists. > > > So, suppose these threads, where: > > > - T1 uses a borrowed reference, and > > > - T2 is releasing the reference (close, release): > > > > Nit: T2 is releasing the *last* reference (as implied by your reference > > to close/release). > > Correct. > > > > > > T1 | T2 > > > kvm_get_kvm() | > > > ... | kvm_put_kvm() > > > kvm_put_kvm_no_destroy() | > > > > > > The above would not trigger a use-after-free bug, but will cause a > > > memory leak. Is my above understanding right? > > > > Yes, this is correct. > > > > Then, what would not be a bug before (using kvm_put_kvm()) now is a > memory leak (using kvm_put_kvm_no_destroy()). No, using kvm_put_kvm_no_destroy() changes how a bug would manifest, as you note below. Replacing kvm_put_kvm() with kvm_put_kvm_no_destroy() when the refcount is _guaranteed_ to be >1 has no impact on correctness. > And it's the price to avoid use-after-free on other cases, which is a > worse bug. Ok, I get it. > > > Paolo > > On Tue, 2019-11-26 at 10:14 -0800, Sean Christopherson wrote: > > If one these kvm_put_kvm() calls did unexpectedly free @kvm (due to > > a bug somewhere else), KVM would still hit a use-after-free scenario > > as the caller still thinks @kvm is valid. Currently, this would > > only happen on a subsequent ioctl() on the caller's file descriptor > > (which holds a pointer to @kvm), as the callers of these functions > > don't directly dereference @kvm after the functions return. But, > > not deferencing @kvm isn't deliberate or functionally required, it's > > just how the code happens to be written. > > So, testing if the kvm reference is valid before running ioctl would be > enough to avoid these bugs? No, the only way to avoid use-after-free bugs of this nature is to not screw up the refcounting :-) This funky "borrowed reference" pattern is not very common. It's necessary here because KVM needs to take an extra reference to itself on behalf of the child device before installing the child's file descriptor, because once the fd is installed it can be closed by userspace and free the child's reference. The error path, which uses kvm_put_kvm_no_destroy(), is used if and only if installing the fd fails, in which case the extra reference is deliberately thrown away. kvm_put_kvm_no_destroy() is asserting "N > 0" as a way to detect a refcounting bug that wouldn't be detected (until later) by the normal refcounting behavior, which asserts "N >= 0". > Is it possible? No. Similar to above, userspace gets a fd by doing open("/dev/kvm"), and the semantics of KVM are such that each fd is a reference to KVM. From userspace's perspective, having a valid fd *is* how it knows that it has a valid KVM reference. > Humm, but if it frees kvm before running ->release(), would it mean the > VM is destroyed incorrectly, and will probably crash? More than likely the host will crash due to corrupting memory. The guest will crash too, but that's a secondary concern.