From patchwork Tue Mar 15 13:43:11 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mimi Zohar X-Patchwork-Id: 8588431 Return-Path: X-Original-To: patchwork-linux-fsdevel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 99E0DC0553 for ; Tue, 15 Mar 2016 13:54:45 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 985182027D for ; Tue, 15 Mar 2016 13:54:44 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 746172024C for ; Tue, 15 Mar 2016 13:54:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S965042AbcCONym (ORCPT ); Tue, 15 Mar 2016 09:54:42 -0400 Received: from [125.16.236.4] ([125.16.236.4]:46925 "EHLO e28smtp04.in.ibm.com" rhost-flags-FAIL-FAIL-OK-OK) by vger.kernel.org with ESMTP id S964881AbcCONyl (ORCPT ); Tue, 15 Mar 2016 09:54:41 -0400 Received: from localhost by e28smtp04.in.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Tue, 15 Mar 2016 19:13:51 +0530 Received: from d28relay04.in.ibm.com (9.184.220.61) by e28smtp04.in.ibm.com (192.168.1.134) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Tue, 15 Mar 2016 19:13:49 +0530 X-IBM-Helo: d28relay04.in.ibm.com X-IBM-MailFrom: zohar@linux.vnet.ibm.com X-IBM-RcptTo: linux-fsdevel@vger.kernel.org; linux-security-module@vger.kernel.org Received: from d28av02.in.ibm.com (d28av02.in.ibm.com [9.184.220.64]) by d28relay04.in.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id u2FDhQNr10682746; Tue, 15 Mar 2016 19:13:26 +0530 Received: from d28av02.in.ibm.com (localhost [127.0.0.1]) by d28av02.in.ibm.com (8.14.4/8.14.4/NCO v10.0 AVout) with ESMTP id u2FDhlsx007848; Tue, 15 Mar 2016 19:13:47 +0530 Received: from localhost.localdomain.localdomain ([9.80.90.248]) by d28av02.in.ibm.com (8.14.4/8.14.4/NCO v10.0 AVin) with ESMTP id u2FDhFSx005849; Tue, 15 Mar 2016 19:13:40 +0530 From: Mimi Zohar To: linux-security-module Cc: Mimi Zohar , linux-fsdevel@vger.kernel.org, "Al Viro <" Subject: [PATCH v2 2/2] ima: add support for creating files using the mknodat syscall Date: Tue, 15 Mar 2016 09:43:11 -0400 Message-Id: <1458049391-26620-3-git-send-email-zohar@linux.vnet.ibm.com> X-Mailer: git-send-email 2.1.0 In-Reply-To: <1458049391-26620-1-git-send-email-zohar@linux.vnet.ibm.com> References: <1458049391-26620-1-git-send-email-zohar@linux.vnet.ibm.com> X-TM-AS-MML: disable x-cbid: 16031513-0013-0000-0000-00000AD3827D Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Commit 3034a14 "ima: pass 'opened' flag to identify newly created files" stopped identifying empty files as new files. However new empty files can be created using the mknodat syscall. On systems with IMA-appraisal enabled, these empty files are not labeled with security.ima extended attributes properly, preventing them from subsequently being opened in order to write the file data contents. This patch defines a new hook named ima_post_path_mknod() to mark these empty files, created using mknodat, as new in order to allow the file data contents to be written. In addition, files with security.ima xattrs containing a file signature are considered "immutable" and can not be modified. The file contents need to be written, before signing the file. This patch relaxes this requirement for new files, allowing the file signature to be written before the file contents. Changelog: - defer identifying files with signatures stored as security.ima (reported by Dmitry Rozhkov ) Signed-off-by: Mimi Zohar Cc: Al Viro < Tested-by: Dmitry Rozhkov --- fs/namei.c | 2 ++ include/linux/ima.h | 6 ++++++ security/integrity/ima/ima_appraise.c | 5 +++++ security/integrity/ima/ima_main.c | 32 +++++++++++++++++++++++++++++++- 4 files changed, 44 insertions(+), 1 deletion(-) diff --git a/fs/namei.c b/fs/namei.c index f624d13..30b5254 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -3620,6 +3620,8 @@ retry: switch (mode & S_IFMT) { case 0: case S_IFREG: error = vfs_create(path.dentry->d_inode,dentry,mode,true); + if (!error) + ima_post_path_mknod(dentry); break; case S_IFCHR: case S_IFBLK: error = vfs_mknod(path.dentry->d_inode,dentry,mode, diff --git a/include/linux/ima.h b/include/linux/ima.h index e6516cb..0eb7c2e 100644 --- a/include/linux/ima.h +++ b/include/linux/ima.h @@ -21,6 +21,7 @@ extern int ima_file_mmap(struct file *file, unsigned long prot); extern int ima_read_file(struct file *file, enum kernel_read_file_id id); extern int ima_post_read_file(struct file *file, void *buf, loff_t size, enum kernel_read_file_id id); +extern void ima_post_path_mknod(struct dentry *dentry); #else static inline int ima_bprm_check(struct linux_binprm *bprm) @@ -54,6 +55,11 @@ static inline int ima_post_read_file(struct file *file, void *buf, loff_t size, return 0; } +static inline void ima_post_path_mknod(struct dentry *dentry) +{ + return; +} + #endif /* CONFIG_IMA */ #ifdef CONFIG_IMA_APPRAISE diff --git a/security/integrity/ima/ima_appraise.c b/security/integrity/ima/ima_appraise.c index d2f28a0..1bcbc12 100644 --- a/security/integrity/ima/ima_appraise.c +++ b/security/integrity/ima/ima_appraise.c @@ -275,6 +275,11 @@ out: xattr_value->type != EVM_IMA_XATTR_DIGSIG)) { if (!ima_fix_xattr(dentry, iint)) status = INTEGRITY_PASS; + } else if ((inode->i_size == 0) && + (iint->flags & IMA_NEW_FILE) && + (xattr_value && + xattr_value->type == EVM_IMA_XATTR_DIGSIG)) { + status = INTEGRITY_PASS; } integrity_audit_msg(AUDIT_INTEGRITY_DATA, inode, filename, op, cause, rc, 0); diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c index 391f417..3297270 100644 --- a/security/integrity/ima/ima_main.c +++ b/security/integrity/ima/ima_main.c @@ -246,7 +246,8 @@ static int process_measurement(struct file *file, char *buf, loff_t size, ima_audit_measurement(iint, pathname); out_digsig: - if ((mask & MAY_WRITE) && (iint->flags & IMA_DIGSIG)) + if ((mask & MAY_WRITE) && (iint->flags & IMA_DIGSIG) && + !(iint->flags & IMA_NEW_FILE)) rc = -EACCES; kfree(xattr_value); out_free: @@ -316,6 +317,35 @@ int ima_file_check(struct file *file, int mask, int opened) EXPORT_SYMBOL_GPL(ima_file_check); /** + * ima_post_path_mknod - mark as a new inode + * @dentry: newly created dentry + * + * Mark files created via the mknodat syscall as new, so that the + * file data can be written later. + */ +void ima_post_path_mknod(struct dentry *dentry) +{ + struct integrity_iint_cache *iint; + struct inode *inode; + int must_appraise; + + if (!dentry || !dentry->d_inode) + return; + + inode = dentry->d_inode; + if (inode->i_size != 0) + return; + + must_appraise = ima_must_appraise(inode, MAY_ACCESS, FILE_CHECK); + if (!must_appraise) + return; + + iint = integrity_inode_get(inode); + if (iint) + iint->flags |= IMA_NEW_FILE; +} + +/** * ima_read_file - pre-measure/appraise hook decision based on policy * @file: pointer to the file to be measured/appraised/audit * @read_id: caller identifier