Received: by 2002:ac0:98c7:0:0:0:0:0 with SMTP id g7-v6csp1439484imd; Thu, 1 Nov 2018 15:55:50 -0700 (PDT) X-Google-Smtp-Source: AJdET5ctnN47axgRPbdMw9MF40+gxb+8a80Pn41l9KDVHjos7cno56OFqVnPFHUZLVDtV9DrS9wF X-Received: by 2002:aa7:8685:: with SMTP id d5-v6mr9396006pfo.58.1541112950426; Thu, 01 Nov 2018 15:55:50 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1541112950; cv=none; d=google.com; s=arc-20160816; b=JoKe1QTurv3DQBEZaDr05Fvn38TbmCKQrUHLvroqZIfN3ARQ2WLkMWr22RVX9kFn+K A/dkUEi8K3SscPR+rM7y5/A4dS1u+7EstxxLmGxfK7vf+mqQAkUlAIeILNxvjcMPDP3L 2PkWjEWW/6KF6GvqM2tHM4q1qIfwxUDQW0h2S/K/+iA/iko/zXBnhh/vtY44TWqLM0qz XCHEx0xdDTgi3GYA2FyipT069tAp5MSTigHuGeon2ygslitgww0ZnDB4GR8+KQcIgFRv JArcKKJN7wEMZrBPtjuEpoI/TX2fSl6ufhTAclbagWVMmcQGytHJoMI+nR3cVnGyV/Jn HdrQ== 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 :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=l3cpqlG7GHq7atMJrxc1tIlBbWOhnB+YUjN51d393HI=; b=I2c0oGsCsX7TkbMhLOX00K9IaVovDW6OqL/rKGxBMq1BtG3Zld2sFCnRfpTjr65oZv WBCVo4Y7Y6VTq0Pl2l5o6znPrp+mH+Bm71D2nXimbF9U4c6/U31HRX7TmSKZm8i8zQrq NNPUn2VzgE0OUolqIj0bLZAcawp86Z2Qqf2cu9ZBn3KONJbxRIo8b1kKYroIS8Eau/Sn 9uQTcFUF7dtSL8DdFOfaWNAzhdV9IuEBvzH9VTYL3SgLeq3utbRgCfRYKEaVmv7r94ao ZO6sI2EWp7zjSTzzItPsRymNeF2JeB0091oUI/8nqkUC1UQP/tBbEHC21BwbuJ7hy7Jg rjLw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=hAPcJtF3; 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; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id x20-v6si32708613pga.475.2018.11.01.15.55.35; Thu, 01 Nov 2018 15:55:50 -0700 (PDT) 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=hAPcJtF3; 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; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728170AbeKBH7R (ORCPT + 99 others); Fri, 2 Nov 2018 03:59:17 -0400 Received: from mail.kernel.org ([198.145.29.99]:52158 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728072AbeKBH7R (ORCPT ); Fri, 2 Nov 2018 03:59:17 -0400 Received: from ebiggers-linuxstation.kir.corp.google.com (unknown [104.132.51.88]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id EFBAE2084C; Thu, 1 Nov 2018 22:54:16 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1541112857; bh=b3QHRP8YQqlEGz0tStooS8qoUx6+xZnHbUaWpaBLfuw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=hAPcJtF3Hzy88pY/EPlY6QG8e40f21qSv7o1jvok3nWI9vAt/Rj8d+2k+a+B0CsgH rlUcL0W5z23YgF2OikvUnIkvArKLODb54l4L+LK6kWfSkF5j+sbWfIaBMEZYWjywtq Gy/Jwi5EajAGtsDvBxJbL7/S9lmiIpY7qL7QtFS4= From: Eric Biggers To: linux-fscrypt@vger.kernel.org Cc: linux-fsdevel@vger.kernel.org, linux-ext4@vger.kernel.org, linux-f2fs-devel@lists.sourceforge.net, linux-integrity@vger.kernel.org, linux-kernel@vger.kernel.org, "Theodore Y . Ts'o" , Jaegeuk Kim , Victor Hsieh , Chandan Rajendra Subject: [PATCH v2 05/12] fs-verity: implement FS_IOC_ENABLE_VERITY ioctl Date: Thu, 1 Nov 2018 15:52:23 -0700 Message-Id: <20181101225230.88058-6-ebiggers@kernel.org> X-Mailer: git-send-email 2.19.1.568.g152ad8e336-goog In-Reply-To: <20181101225230.88058-1-ebiggers@kernel.org> References: <20181101225230.88058-1-ebiggers@kernel.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Eric Biggers Add a function for filesystems to call to implement the FS_IOC_ENABLE_VERITY ioctl. This ioctl enables fs-verity on a file, after userspace has appended verity metadata to it. This ioctl is documented in Documentation/filesystem/fsverity.rst; see there for more information. Signed-off-by: Eric Biggers --- fs/verity/Makefile | 2 +- fs/verity/ioctl.c | 117 +++++++++++++++++++++++++++++++++++++++ include/linux/fsverity.h | 11 ++++ 3 files changed, 129 insertions(+), 1 deletion(-) create mode 100644 fs/verity/ioctl.c diff --git a/fs/verity/Makefile b/fs/verity/Makefile index a6c7cefb61ab7..6450925e3a8b7 100644 --- a/fs/verity/Makefile +++ b/fs/verity/Makefile @@ -1,3 +1,3 @@ obj-$(CONFIG_FS_VERITY) += fsverity.o -fsverity-y := hash_algs.o setup.o verify.o +fsverity-y := hash_algs.o ioctl.o setup.o verify.o diff --git a/fs/verity/ioctl.c b/fs/verity/ioctl.c new file mode 100644 index 0000000000000..c5f0022cb3bef --- /dev/null +++ b/fs/verity/ioctl.c @@ -0,0 +1,117 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * fs/verity/ioctl.c: fs-verity ioctls + * + * Copyright 2018 Google LLC + * + * Originally written by Jaegeuk Kim and Michael Halcrow; + * heavily rewritten by Eric Biggers. + */ + +#include "fsverity_private.h" + +#include +#include +#include + +/** + * fsverity_ioctl_enable - enable fs-verity on a file + * + * Enable fs-verity on a file. Verity metadata must have already been appended + * to the file. See Documentation/filesystems/fsverity.rst, section + * 'FS_IOC_ENABLE_VERITY' for details. + * + * Return: 0 on success, -errno on failure + */ +int fsverity_ioctl_enable(struct file *filp, const void __user *arg) +{ + struct inode *inode = file_inode(filp); + struct fsverity_info *vi; + int err; + + err = inode_permission(inode, MAY_WRITE); + if (err) + return err; + + if (IS_APPEND(inode)) + return -EPERM; + + if (arg) /* argument is reserved */ + return -EINVAL; + + if (S_ISDIR(inode->i_mode)) + return -EISDIR; + + if (!S_ISREG(inode->i_mode)) + return -EINVAL; + + err = mnt_want_write_file(filp); + if (err) + goto out; + + /* + * Temporarily lock out writers via writable file descriptors or + * truncate(). This should stabilize the contents of the file as well + * as its size. Note that at the end of this ioctl we will unlock + * writers, but at that point the verity bit will be set (if the ioctl + * succeeded), preventing future writers. + */ + err = deny_write_access(filp); + if (err) /* -ETXTBSY */ + goto out_drop_write; + + /* + * fsync so that the verity bit can't be persisted to disk prior to the + * data, causing verification errors after a crash. + */ + err = vfs_fsync(filp, 1); + if (err) + goto out_allow_write; + + /* Serialize concurrent use of this ioctl on the same inode */ + inode_lock(inode); + + if (get_fsverity_info(inode)) { /* fs-verity already enabled? */ + err = -EEXIST; + goto out_unlock; + } + + /* Validate the verity metadata */ + vi = create_fsverity_info(inode, true); + if (IS_ERR(vi)) { + err = PTR_ERR(vi); + if (err == -EINVAL) /* distinguish "invalid metadata" case */ + err = -EBADMSG; + goto out_unlock; + } + + /* + * Ask the filesystem to mark the file as a verity file, e.g. by setting + * the verity bit in the inode. + */ + err = inode->i_sb->s_vop->set_verity(inode, vi->data_i_size); + if (err) + goto out_free_vi; + + /* Invalidate all cached pages, forcing re-verification */ + truncate_inode_pages(inode->i_mapping, 0); + + /* + * Set ->i_verity_info, unless another task managed to do it already + * between ->set_verity() and here. + */ + if (set_fsverity_info(inode, vi)) + vi = NULL; + err = 0; +out_free_vi: + free_fsverity_info(vi); +out_unlock: + inode_unlock(inode); +out_allow_write: + allow_write_access(filp); +out_drop_write: + mnt_drop_write_file(filp); +out: + return err; +} +EXPORT_SYMBOL_GPL(fsverity_ioctl_enable); diff --git a/include/linux/fsverity.h b/include/linux/fsverity.h index 15478fe7d55aa..5de50b52ccc70 100644 --- a/include/linux/fsverity.h +++ b/include/linux/fsverity.h @@ -21,6 +21,9 @@ struct fsverity_operations { #if __FS_HAS_VERITY +/* ioctl.c */ +extern int fsverity_ioctl_enable(struct file *filp, const void __user *arg); + /* setup.c */ extern int fsverity_file_open(struct inode *inode, struct file *filp); extern int fsverity_prepare_setattr(struct dentry *dentry, struct iattr *attr); @@ -40,6 +43,14 @@ static inline bool fsverity_check_hole(struct inode *inode, struct page *page) #else /* !__FS_HAS_VERITY */ +/* ioctl.c */ + +static inline int fsverity_ioctl_enable(struct file *filp, + const void __user *arg) +{ + return -EOPNOTSUPP; +} + /* setup.c */ static inline int fsverity_file_open(struct inode *inode, struct file *filp) -- 2.19.1.568.g152ad8e336-goog