From patchwork Mon Oct 24 09:21:50 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Haozhong Zhang X-Patchwork-Id: 9391785 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 593DE60231 for ; Mon, 24 Oct 2016 09:26:30 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 48E2B28E20 for ; Mon, 24 Oct 2016 09:26:30 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 3D94128E47; Mon, 24 Oct 2016 09:26:30 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id AB6D128E20 for ; Mon, 24 Oct 2016 09:26:29 +0000 (UTC) Received: from localhost ([::1]:45451 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bybWW-00041C-SO for patchwork-qemu-devel@patchwork.kernel.org; Mon, 24 Oct 2016 05:26:28 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:42149) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bybSU-0000wM-Vq for qemu-devel@nongnu.org; Mon, 24 Oct 2016 05:22:20 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1bybSR-0004qW-Qy for qemu-devel@nongnu.org; Mon, 24 Oct 2016 05:22:18 -0400 Received: from mga03.intel.com ([134.134.136.65]:49655) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1bybSR-0004qB-IT for qemu-devel@nongnu.org; Mon, 24 Oct 2016 05:22:15 -0400 Received: from orsmga001.jf.intel.com ([10.7.209.18]) by orsmga103.jf.intel.com with ESMTP; 24 Oct 2016 02:22:14 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos; i="5.31,541,1473145200"; d="scan'208"; a="1049138384" Received: from hz-desktop.sh.intel.com (HELO localhost) ([10.239.159.148]) by orsmga001.jf.intel.com with ESMTP; 24 Oct 2016 02:22:13 -0700 From: Haozhong Zhang To: qemu-devel@nongnu.org, Eduardo Habkost , Igor Mammedov Date: Mon, 24 Oct 2016 17:21:50 +0800 Message-Id: <20161024092151.32386-2-haozhong.zhang@intel.com> X-Mailer: git-send-email 2.10.1 In-Reply-To: <20161024092151.32386-1-haozhong.zhang@intel.com> References: <20161024092151.32386-1-haozhong.zhang@intel.com> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 134.134.136.65 Subject: [Qemu-devel] [PATCH 1/2] exec.c: do not truncate non-empty memory backend file X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Paolo Bonzini , Richard Henderson , Xiao Guangrong , Haozhong Zhang , Peter Crosthwaite Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP For '-object memory-backend-file,mem-path=foo,size=xyz', if the size of file 'foo' does not match the given size 'xyz', the current QEMU will truncate the file to the given size, which may corrupt the existing data in that file. To avoid such data corruption, this patch disables truncating non-empty backend files. Signed-off-by: Haozhong Zhang --- exec.c | 37 ++++++++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/exec.c b/exec.c index e63c5a1..95983c9 100644 --- a/exec.c +++ b/exec.c @@ -1188,6 +1188,15 @@ void qemu_mutex_unlock_ramlist(void) } #ifdef __linux__ +static int64_t get_file_size(int fd) +{ + int64_t size = lseek(fd, 0, SEEK_END); + if (size < 0) { + return -errno; + } + return size; +} + static void *file_ram_alloc(RAMBlock *block, ram_addr_t memory, const char *path, @@ -1199,6 +1208,7 @@ static void *file_ram_alloc(RAMBlock *block, char *c; void *area = MAP_FAILED; int fd = -1; + int64_t file_size; if (kvm_enabled() && !kvm_has_sync_mmu()) { error_setg(errp, @@ -1256,6 +1266,14 @@ static void *file_ram_alloc(RAMBlock *block, block->page_size = qemu_fd_getpagesize(fd); block->mr->align = MAX(block->page_size, QEMU_VMALLOC_ALIGN); + file_size = get_file_size(fd); + if (file_size < 0) { + error_setg_errno(errp, file_size, + "can't get size of backing store %s", + path); + goto error; + } + if (memory < block->page_size) { error_setg(errp, "memory size 0x" RAM_ADDR_FMT " must be equal to " "or larger than page size 0x%zx", @@ -1266,12 +1284,29 @@ static void *file_ram_alloc(RAMBlock *block, memory = ROUND_UP(memory, block->page_size); /* + * Do not extend/shrink the backend file if it's not empty, or its + * size does not match the aligned 'size=xxx' option. Otherwise, + * it is possible to corrupt the existing data in the file. + * + * Disabling shrinking is not enough. For example, the current + * vNVDIMM implementation stores the guest NVDIMM labels at the + * end of the backend file. If the backend file is later extended, + * QEMU will not be able to find those labels. Therefore, + * extending the non-empty backend file is disabled as well. + */ + if (file_size && file_size != memory) { + error_setg(errp, "backing store %s size %"PRId64 + " does not math with aligned 'size' option %"PRIu64, + path, file_size, memory); + goto error; + } + /* * ftruncate is not supported by hugetlbfs in older * hosts, so don't bother bailing out on errors. * If anything goes wrong with it under other filesystems, * mmap will fail. */ - if (ftruncate(fd, memory)) { + if (!file_size && ftruncate(fd, memory)) { perror("ftruncate"); }