Received: by 2002:ad5:474a:0:0:0:0:0 with SMTP id i10csp2530739imu; Thu, 29 Nov 2018 06:28:59 -0800 (PST) X-Google-Smtp-Source: AFSGD/WGOrxBmvJwMjg9defScFdZNkA6red2u+WpnCPSus2pPWHizQtAigmBqGpVaqRyPksDMJ9x X-Received: by 2002:a17:902:6185:: with SMTP id u5mr1677948plj.194.1543501739843; Thu, 29 Nov 2018 06:28:59 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1543501739; cv=none; d=google.com; s=arc-20160816; b=cxFCMBvKCyRWxroyD0bfcoVXsXYp19L8pAGVGzBhF4cSySIc+DbFVUUT8RlHjD086Z nm81M1WEDz/BaFX/ijHT9B8Y2268GxKjxIaqmQNTwfG6gubHYzFaID8wcO8kOEKuzIdD dLFwhASLiPctGrbQ26HhKezWPf8FiAL1o9XJ0BUfuRu/oEE3HViqXdAmGYb6YteQ7c6B eN5kK+zZfhdOshjpGhO1ypQIELqu8pRbezxJ0YanS85Xs9IBtMYzkOTeytAu2X07eihL ZYGM+/COT+H1l6HiQP7pfIxqGMQ4ulTMrlN5tq0ctElRZaDDhdnKQV0cOAgcaCZwWf5P 77ug== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=hfowxhsoE5cJ79JjNYbZaOtH5GGlybnjDLx+bWFUqP0=; b=gXTU2AKvcIICt78PidUpgPstVtyiHCXow0jPpdEb5zumu3HbrLfnr5Wpw2q4SiTOTA QsvpT+yDJfQWw922i+SH1F2Satubkca4bS+ZiKwJH/Y7PcKWWNYJZxazkT8vH8xPoXy6 G9JYI7jFJsK9TKPY03gPjapaEf4I4SdqSU+YkWszwhgBcd8UdAU4vN+3Fv+QbYzg/84k zErubIqwyviGQx1gdoaQJJrefdWBOOeZ+W1eJAF49q5PUs+d8rBZ5r9OFB540gW9bvsM z7SPQKgeokQmgMGdRICAsCQwFWna34KW9XaP12ZDHp3VTNbb9dNA7TpWldh4JSZKAsN+ IqRA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=qLNsaFIf; 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 69si1744830pgd.290.2018.11.29.06.28.44; Thu, 29 Nov 2018 06:28:59 -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; dkim=pass header.i=@kernel.org header.s=default header.b=qLNsaFIf; 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 S2387897AbeK3Bdc (ORCPT + 99 others); Thu, 29 Nov 2018 20:33:32 -0500 Received: from mail.kernel.org ([198.145.29.99]:34186 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731863AbeK3Bdb (ORCPT ); Thu, 29 Nov 2018 20:33:31 -0500 Received: from localhost (5356596B.cm-6-7b.dynamic.ziggo.nl [83.86.89.107]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 2FF6D2146D; Thu, 29 Nov 2018 14:27:58 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1543501678; bh=BJcQErXZZLDzHfm4wnLouZmDwXKZCdwSffF5pWjt174=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=qLNsaFIfKpwN86Cr1+vnrBctw8pgUvgcj8kUtHZhWXHN1WfP+bk4+63W6Z4yV+PXr 0ek5X71Vl9aaTrxEG85NxBBmcZfuWPWVU9Wdufo6HbZJnzC8FahHeqDDRUjQ/IXvR1 mw2dayoXRoLF2BKTUaV2YZBCK5m1zAM8UM5SPRbE= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Mimi Zohar , Dmitry Kasatkin , Aditya Kali Subject: [PATCH 4.14 097/100] ima: always measure and audit files in policy Date: Thu, 29 Nov 2018 15:13:07 +0100 Message-Id: <20181129140107.150207555@linuxfoundation.org> X-Mailer: git-send-email 2.19.2 In-Reply-To: <20181129140058.768942700@linuxfoundation.org> References: <20181129140058.768942700@linuxfoundation.org> User-Agent: quilt/0.65 X-stable: review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 4.14-stable review patch. If anyone has any objections, please let me know. ------------------ From: Mimi Zohar commit f3cc6b25dcc5616f0d5c720009b2ac66f97df2ff upstream. All files matching a "measure" rule must be included in the IMA measurement list, even when the file hash cannot be calculated. Similarly, all files matching an "audit" rule must be audited, even when the file hash can not be calculated. The file data hash field contained in the IMA measurement list template data will contain 0's instead of the actual file hash digest. Note: In general, adding, deleting or in anyway changing which files are included in the IMA measurement list is not a good idea, as it might result in not being able to unseal trusted keys sealed to a specific TPM PCR value. This patch not only adds file measurements that were not previously measured, but specifies that the file hash value for these files will be 0's. As the IMA measurement list ordering is not consistent from one boot to the next, it is unlikely that anyone is sealing keys based on the IMA measurement list. Remote attestation servers should be able to process these new measurement records, but might complain about these unknown records. Signed-off-by: Mimi Zohar Reviewed-by: Dmitry Kasatkin Cc: Aditya Kali Signed-off-by: Greg Kroah-Hartman --- security/integrity/ima/ima_api.c | 69 ++++++++++++++++++++++-------------- security/integrity/ima/ima_crypto.c | 10 +++++ security/integrity/ima/ima_main.c | 9 ++-- 3 files changed, 57 insertions(+), 31 deletions(-) --- a/security/integrity/ima/ima_api.c +++ b/security/integrity/ima/ima_api.c @@ -199,42 +199,59 @@ int ima_collect_measurement(struct integ struct inode *inode = file_inode(file); const char *filename = file->f_path.dentry->d_name.name; int result = 0; + int length; + void *tmpbuf; + u64 i_version; struct { struct ima_digest_data hdr; char digest[IMA_MAX_DIGEST_SIZE]; } hash; - if (!(iint->flags & IMA_COLLECTED)) { - u64 i_version = file_inode(file)->i_version; + if (iint->flags & IMA_COLLECTED) + goto out; - if (file->f_flags & O_DIRECT) { - audit_cause = "failed(directio)"; - result = -EACCES; - goto out; - } - - hash.hdr.algo = algo; - - result = (!buf) ? ima_calc_file_hash(file, &hash.hdr) : - ima_calc_buffer_hash(buf, size, &hash.hdr); - if (!result) { - int length = sizeof(hash.hdr) + hash.hdr.length; - void *tmpbuf = krealloc(iint->ima_hash, length, - GFP_NOFS); - if (tmpbuf) { - iint->ima_hash = tmpbuf; - memcpy(iint->ima_hash, &hash, length); - iint->version = i_version; - iint->flags |= IMA_COLLECTED; - } else - result = -ENOMEM; - } + /* + * Dectecting file change is based on i_version. On filesystems + * which do not support i_version, support is limited to an initial + * measurement/appraisal/audit. + */ + i_version = file_inode(file)->i_version; + hash.hdr.algo = algo; + + /* Initialize hash digest to 0's in case of failure */ + memset(&hash.digest, 0, sizeof(hash.digest)); + + if (buf) + result = ima_calc_buffer_hash(buf, size, &hash.hdr); + else + result = ima_calc_file_hash(file, &hash.hdr); + + if (result && result != -EBADF && result != -EINVAL) + goto out; + + length = sizeof(hash.hdr) + hash.hdr.length; + tmpbuf = krealloc(iint->ima_hash, length, GFP_NOFS); + if (!tmpbuf) { + result = -ENOMEM; + goto out; } + + iint->ima_hash = tmpbuf; + memcpy(iint->ima_hash, &hash, length); + iint->version = i_version; + + /* Possibly temporary failure due to type of read (eg. O_DIRECT) */ + if (!result) + iint->flags |= IMA_COLLECTED; out: - if (result) + if (result) { + if (file->f_flags & O_DIRECT) + audit_cause = "failed(directio)"; + integrity_audit_msg(AUDIT_INTEGRITY_DATA, inode, filename, "collect_data", audit_cause, result, 0); + } return result; } @@ -278,7 +295,7 @@ void ima_store_measurement(struct integr } result = ima_store_template(entry, violation, inode, filename, pcr); - if (!result || result == -EEXIST) { + if ((!result || result == -EEXIST) && !(file->f_flags & O_DIRECT)) { iint->flags |= IMA_MEASURED; iint->measured_pcrs |= (0x1 << pcr); } --- a/security/integrity/ima/ima_crypto.c +++ b/security/integrity/ima/ima_crypto.c @@ -443,6 +443,16 @@ int ima_calc_file_hash(struct file *file loff_t i_size; int rc; + /* + * For consistency, fail file's opened with the O_DIRECT flag on + * filesystems mounted with/without DAX option. + */ + if (file->f_flags & O_DIRECT) { + hash->length = hash_digest_size[ima_hash_algo]; + hash->algo = ima_hash_algo; + return -EINVAL; + } + i_size = i_size_read(file_inode(file)); if (ima_ahash_minsize && i_size >= ima_ahash_minsize) { --- a/security/integrity/ima/ima_main.c +++ b/security/integrity/ima/ima_main.c @@ -242,11 +242,8 @@ static int process_measurement(struct fi hash_algo = ima_get_hash_algo(xattr_value, xattr_len); rc = ima_collect_measurement(iint, file, buf, size, hash_algo); - if (rc != 0) { - if (file->f_flags & O_DIRECT) - rc = (iint->flags & IMA_PERMIT_DIRECTIO) ? 0 : -EACCES; + if (rc != 0 && rc != -EBADF && rc != -EINVAL) goto out_digsig; - } if (!pathbuf) /* ima_rdwr_violation possibly pre-fetched */ pathname = ima_d_path(&file->f_path, &pathbuf, filename); @@ -254,12 +251,14 @@ static int process_measurement(struct fi if (action & IMA_MEASURE) ima_store_measurement(iint, file, pathname, xattr_value, xattr_len, pcr); - if (action & IMA_APPRAISE_SUBMASK) + if (rc == 0 && (action & IMA_APPRAISE_SUBMASK)) rc = ima_appraise_measurement(func, iint, file, pathname, xattr_value, xattr_len, opened); if (action & IMA_AUDIT) ima_audit_measurement(iint, pathname); + if ((file->f_flags & O_DIRECT) && (iint->flags & IMA_PERMIT_DIRECTIO)) + rc = 0; out_digsig: if ((mask & MAY_WRITE) && (iint->flags & IMA_DIGSIG) && !(iint->flags & IMA_NEW_FILE))