Received: by 2002:ad5:474a:0:0:0:0:0 with SMTP id i10csp2527527imu; Thu, 29 Nov 2018 06:26:22 -0800 (PST) X-Google-Smtp-Source: AFSGD/XGOt+K9a6Ar0gogZe70p0W1zoUYI3lFRVNA0fdx0feCjqVHnAZjuRx61hXhW6bmJMBnKzF X-Received: by 2002:a62:60c5:: with SMTP id u188mr1619160pfb.4.1543501582035; Thu, 29 Nov 2018 06:26:22 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1543501582; cv=none; d=google.com; s=arc-20160816; b=dbKZotKmtIrr7n+1frMANDHJ/hVm13dDQVxnvnG7j5R1WizrbTKD/9AhFU+slAjwGj O44LI+FMNe/8HcJttW0Z/mTFmDZw2aIUrEJnHeByTKchSOHWR7Aur5jKS92s1IBftumv mUnzJE82QNMG91nZDDEVKqip0r2nykiNg9AiZ3PtTvYWG+50sPwYfAadPvOpyi82f4ht BG2auhWnTDxik1SXnaSrribYjwyJBLW+anzTUymGEhW7TI0u0ptjAEKmkPKwBi8/rbQj vY4WPX1zjAf1so2S0ImvBKxLYTt3NmC670PN005yEclWK8a1ZiGO9WEKXJ8jvVMNtGDX QWsg== 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=5nHqE1U0MZaC3edRM6xmJ+EHFt5doP8mNFYuAU4nGaQ=; b=I7S05i4RU2h4CV7yG8E4XypNkiBQY/KP72O1L3ZwF0ORSPiqJm5/nlSkOu2zm2dROI aqwno73ca4iS2vjL4gNobyFKhNvygmfUxbXwo5e79HXfPeK3RQ0dk86FAMSe0NBs5pwl /Rcf7Zi4KTayoG1e9RNwVBGCymAVzCLpNlpaTPg6hmS76Il4n8ZPZRqWFcW7MHSiFJUd ov53bI9qOsiXzqpGWYw1tpwEijppPVLwirSNuBDpQRHK95bhlrWffmpmN/HseAOPcQjD fkm7vyAIuPnc0+N9sa9Cf2SSafTNFWGTc9Di5OjvEl1PjHQ8+8WGmqnayCWIltJtOrJ8 vsMQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=drUHtXjN; 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 2si2315081pla.156.2018.11.29.06.26.06; Thu, 29 Nov 2018 06:26: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; dkim=pass header.i=@kernel.org header.s=default header.b=drUHtXjN; 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 S1732482AbeK3B3a (ORCPT + 99 others); Thu, 29 Nov 2018 20:29:30 -0500 Received: from mail.kernel.org ([198.145.29.99]:55948 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1732472AbeK3B33 (ORCPT ); Thu, 29 Nov 2018 20:29:29 -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 7C53521104; Thu, 29 Nov 2018 14:23:57 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1543501437; bh=tpCxkAUeRc0dv3fAL9VAv+KTk/a2CSSi9ZmweOMu6Xc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=drUHtXjNCui1P6DWuf5gTtnVJLXnggNn5+1PRZdf0GBaOFWQ1yHSVJJq9EDzRvM/h cvelqu8sfowV/DdT6Y6dey7+OKaEwdiObznhxSbK/K8fmJADa339ay8VU9UMyRIBuK KOOq5Fy1ix0oIOQQ5Tu7Mcs60hQgKo1G0zleJ/HM= 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.9 89/92] ima: always measure and audit files in policy Date: Thu, 29 Nov 2018 15:12:58 +0100 Message-Id: <20181129140113.954940411@linuxfoundation.org> X-Mailer: git-send-email 2.19.2 In-Reply-To: <20181129140106.520639693@linuxfoundation.org> References: <20181129140106.520639693@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.9-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 @@ -198,42 +198,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; } @@ -277,7 +294,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))