Received: by 10.223.185.116 with SMTP id b49csp6367917wrg; Wed, 28 Feb 2018 08:15:55 -0800 (PST) X-Google-Smtp-Source: AH8x226kviQ+qtt+RYRlTHevqa6eUf3AgczeFkTX4SMaPkOCGRETU5ECKkoxnAWiDVlgiuOXR7Bs X-Received: by 10.98.219.129 with SMTP id f123mr18453324pfg.195.1519834555368; Wed, 28 Feb 2018 08:15:55 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1519834555; cv=none; d=google.com; s=arc-20160816; b=jdgttZAaKMI6MU3utW1jfKmScGKgWmINWP4VnoztcHTqQ6E2QuR1zB2j983mtD/9E+ a3rVXtlK+aGuIQetUjbQ57j5qQh0+xevJ26dKLRue/ytQY+C6BCyxTpDJFkhX1XwNvt0 OJ/+OQ9mKaii05OO2kI853MM/8PuVJBimYaYVIWoLL/pt9kfw1lPwFf2rA4wo/JgCoXc EgzYzrFE1LiKpfsveXM3d2mfzYNKmv/PujN0Lr4pjpJvruZRU7SKXzCr96Ho7zqMCdFW IFG1Z6GAJznJEYcSYs2TsxLZ1crwdXjQoHJV6bDJEClxIO2hRJcV2Do0FWXlyjjVKbwD 4DHw== 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:subject:message-id:date:cc:to :from:mime-version:content-transfer-encoding:content-disposition :arc-authentication-results; bh=UNdbRTmHyM+kwZge79/vL56fav7rEPlOxEUnSVJ1gEg=; b=h0N2WLIPZN4g4HOGkbQrO7EMDtGpoHvNnOeEQXQ1EnmcdCFoOZOwoxsWADDL2jZ9Nm laaOsNq4rlsDEpXjMFKZ96N/k7ydpTBRIPweGUJ7CVgUiYFtYqH2ccazIksIp58C+7XX FuOg73HF2XI9rcc9Oo2sqEWLSoSfzvm+tM7S2rwMRXC1+my50BQOYvGTOKGy6pysFXQE 1dzvQQp2jQjBVE7TwuR/m1Cr4CWgBiJIrHqsN/dFf/cnmsvRvUU28HqI90alDVTyP1Gk tfk07onzuYq27ZCJ7yWmL2qViCbBxwgDh25I+0TRJ7R/3YFcZ+JPnH1Ag79pv1LGl4wz ZwUw== 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 Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id r4si1153400pgs.323.2018.02.28.08.15.40; Wed, 28 Feb 2018 08:15:55 -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 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S934626AbeB1QNn (ORCPT + 99 others); Wed, 28 Feb 2018 11:13:43 -0500 Received: from shadbolt.e.decadent.org.uk ([88.96.1.126]:35063 "EHLO shadbolt.e.decadent.org.uk" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S933070AbeB1QNi (ORCPT ); Wed, 28 Feb 2018 11:13:38 -0500 Received: from [2a02:8011:400e:2:6f00:88c8:c921:d332] (helo=deadeye) by shadbolt.decadent.org.uk with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.84_2) (envelope-from ) id 1er3Yu-0006Xh-C4; Wed, 28 Feb 2018 15:22:32 +0000 Received: from ben by deadeye with local (Exim 4.90_1) (envelope-from ) id 1er3Yd-0008OV-Nc; Wed, 28 Feb 2018 15:22:15 +0000 Content-Type: text/plain; charset="UTF-8" Content-Disposition: inline Content-Transfer-Encoding: 8bit MIME-Version: 1.0 From: Ben Hutchings To: linux-kernel@vger.kernel.org, stable@vger.kernel.org CC: akpm@linux-foundation.org, "Long Li" , "K. Y. Srinivasan" , "Paul Meyer" , "Greg Kroah-Hartman" Date: Wed, 28 Feb 2018 15:20:18 +0000 Message-ID: X-Mailer: LinuxStableQueue (scripts by bwh) Subject: [PATCH 3.16 029/254] hv: kvp: Avoid reading past allocated blocks from KVP file In-Reply-To: X-SA-Exim-Connect-IP: 2a02:8011:400e:2:6f00:88c8:c921:d332 X-SA-Exim-Mail-From: ben@decadent.org.uk X-SA-Exim-Scanned: No (on shadbolt.decadent.org.uk); SAEximRunCond expanded to false Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 3.16.55-rc1 review patch. If anyone has any objections, please let me know. ------------------ From: Paul Meyer commit 297d6b6e56c2977fc504c61bbeeaa21296923f89 upstream. While reading in more than one block (50) of KVP records, the allocation goes per block, but the reads used the total number of allocated records (without resetting the pointer/stream). This causes the records buffer to overrun when the refresh reads more than one block over the previous capacity (e.g. reading more than 100 KVP records whereas the in-memory database was empty before). Fix this by reading the correct number of KVP records from file each time. Signed-off-by: Paul Meyer Signed-off-by: Long Li Signed-off-by: K. Y. Srinivasan Signed-off-by: Greg Kroah-Hartman Signed-off-by: Ben Hutchings --- tools/hv/hv_kvp_daemon.c | 70 ++++++++++-------------------------------------- 1 file changed, 14 insertions(+), 56 deletions(-) --- a/tools/hv/hv_kvp_daemon.c +++ b/tools/hv/hv_kvp_daemon.c @@ -196,11 +196,14 @@ static void kvp_update_mem_state(int poo for (;;) { readp = &record[records_read]; records_read += fread(readp, sizeof(struct kvp_record), - ENTRIES_PER_BLOCK * num_blocks, - filep); + ENTRIES_PER_BLOCK * num_blocks - records_read, + filep); if (ferror(filep)) { - syslog(LOG_ERR, "Failed to read file, pool: %d", pool); + syslog(LOG_ERR, + "Failed to read file, pool: %d; error: %d %s", + pool, errno, strerror(errno)); + kvp_release_lock(pool); exit(EXIT_FAILURE); } @@ -213,6 +216,7 @@ static void kvp_update_mem_state(int poo if (record == NULL) { syslog(LOG_ERR, "malloc failed"); + kvp_release_lock(pool); exit(EXIT_FAILURE); } continue; @@ -227,15 +231,11 @@ static void kvp_update_mem_state(int poo fclose(filep); kvp_release_lock(pool); } + static int kvp_file_init(void) { int fd; - FILE *filep; - size_t records_read; char *fname; - struct kvp_record *record; - struct kvp_record *readp; - int num_blocks; int i; int alloc_unit = sizeof(struct kvp_record) * ENTRIES_PER_BLOCK; @@ -249,61 +249,19 @@ static int kvp_file_init(void) for (i = 0; i < KVP_POOL_COUNT; i++) { fname = kvp_file_info[i].fname; - records_read = 0; - num_blocks = 1; sprintf(fname, "%s/.kvp_pool_%d", KVP_CONFIG_LOC, i); fd = open(fname, O_RDWR | O_CREAT | O_CLOEXEC, 0644 /* rw-r--r-- */); if (fd == -1) return 1; - - filep = fopen(fname, "re"); - if (!filep) { - close(fd); - return 1; - } - - record = malloc(alloc_unit * num_blocks); - if (record == NULL) { - fclose(filep); - close(fd); - return 1; - } - for (;;) { - readp = &record[records_read]; - records_read += fread(readp, sizeof(struct kvp_record), - ENTRIES_PER_BLOCK, - filep); - - if (ferror(filep)) { - syslog(LOG_ERR, "Failed to read file, pool: %d", - i); - exit(EXIT_FAILURE); - } - - if (!feof(filep)) { - /* - * We have more data to read. - */ - num_blocks++; - record = realloc(record, alloc_unit * - num_blocks); - if (record == NULL) { - fclose(filep); - close(fd); - return 1; - } - continue; - } - break; - } kvp_file_info[i].fd = fd; - kvp_file_info[i].num_blocks = num_blocks; - kvp_file_info[i].records = record; - kvp_file_info[i].num_records = records_read; - fclose(filep); - + kvp_file_info[i].num_blocks = 1; + kvp_file_info[i].records = malloc(alloc_unit); + if (kvp_file_info[i].records == NULL) + return 1; + kvp_file_info[i].num_records = 0; + kvp_update_mem_state(i); } return 0;