From patchwork Thu Oct 4 20:30:05 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matthew Garrett X-Patchwork-Id: 10626663 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 24310184E for ; Thu, 4 Oct 2018 20:30:16 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 189C32972C for ; Thu, 4 Oct 2018 20:30:16 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 0D31B2972F; Thu, 4 Oct 2018 20:30:16 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.5 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI, USER_IN_DEF_DKIM_WL autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id A13E72972C for ; Thu, 4 Oct 2018 20:30:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727805AbeJEDZJ (ORCPT ); Thu, 4 Oct 2018 23:25:09 -0400 Received: from mail-qt1-f201.google.com ([209.85.160.201]:49592 "EHLO mail-qt1-f201.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727802AbeJEDZI (ORCPT ); Thu, 4 Oct 2018 23:25:08 -0400 Received: by mail-qt1-f201.google.com with SMTP id f20-v6so9677037qta.16 for ; Thu, 04 Oct 2018 13:30:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=2xzpPNyQptjlKIAzX7rJhGAFIT47yBSuCeTxyClfXio=; b=WBT2lrNK0d4AUYRzPzVSVuv8rm9DULRFWzknjovgSbUzjevTEjWNIB7M7G28pGg49X hLtRtjRe9gRoXwYZTwU6VZO+NtkHA0nS3zNCOWQfLx6yvPGF8V2MxxjFSwc3berPq9nf nzP6AoK54ZOYgn8T8Vc/R4sXttMlxjPCNEKnLe266aEwhDR3MxseTD1rrRRgr2ARPPHu H5NnIEFLu65v1yPuEivoPdC0RZT6KNL0uy6tfVaBXOAnIF85LsVOVXyU7iGjKwjawpg/ yWgJMi7G9fQuEqra/KQhoz3WBOAEJNxYI9uvEbSivbPivtjwjq/De59INeM+Yi+XQkGV Fanw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=2xzpPNyQptjlKIAzX7rJhGAFIT47yBSuCeTxyClfXio=; b=N73G6FkaJeuhehEymgakN7KFAVyHS9r5dqXUjeQzwYFcGUSam2rmq4x/5yEDZZUJEY f3p0yyKstnecXHnCKoOlCdLMfInm468JIi4DEv4QEPlrVsdO5PBz/f6Hvdi8KQ5pQ26r zFE90GX5OwnbDGmjD7gVMVvk5Qyp4xkIpg//ca+20+cq9ahCkwBQWmj4NK0Thx1CYb+a CcppeuvFEeYOvA2322YGIiqTsKZwgTx/V3T7/DBS4weY6nTnMGiGDLm4eAxyB7bXdtXD ZqvikYzvid4DtnElQKLYr8r9dCwW420iAxi6t75JL3FPIGPc5qVJ4Q4AbWAO1iJZWK7W 7QpQ== X-Gm-Message-State: ABuFfohIFLWal0wUORLExETaP6wA6qFdPET1uyl5BKZs2jQVAJsCGl6y L+E2RlX3aj0esWt4p80J2yHEXgmhmCpaV49vwaUDnQ== X-Google-Smtp-Source: ACcGV62TovjgWMyI7yIlxZpURBhiPuuOZMsWRaZ8CiMfQ0F0kcM7ZVAiRyAwgTcX4G9l7ORUv4JJNIlsYnNGN55pR932Cw== X-Received: by 2002:aed:25b0:: with SMTP id x45-v6mr6169289qtc.4.1538685013277; Thu, 04 Oct 2018 13:30:13 -0700 (PDT) Date: Thu, 4 Oct 2018 13:30:05 -0700 In-Reply-To: <20181004203007.217320-1-mjg59@google.com> Message-Id: <20181004203007.217320-2-mjg59@google.com> Mime-Version: 1.0 References: <20181004203007.217320-1-mjg59@google.com> X-Mailer: git-send-email 2.19.0.605.g01d371f741-goog Subject: [PATCH 1/3] VFS: Add a call to obtain a file's hash From: Matthew Garrett To: linux-integrity@vger.kernel.org Cc: zohar@linux.vnet.ibm.com, dmitry.kasatkin@gmail.com, miklos@szeredi.hu, linux-fsdevel@vger.kernel.org, viro@zeniv.linux.org.uk, Matthew Garrett Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP IMA wants to know what the hash of a file is, and currently does so by reading the entire file and generating the hash. Some filesystems may have the ability to store the hash in a secure manner resistant to offline attacks (eg, filesystem-level file signing), and in that case it's a performance win for IMA to be able to use that rather than having to re-hash everything. This patch simply adds VFS-level support for calling down to filesystems. Signed-off-by: Matthew Garrett --- fs/read_write.c | 24 ++++++++++++++++++++++++ include/linux/fs.h | 6 +++++- 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/fs/read_write.c b/fs/read_write.c index 39b4a21dd933..9ba3ce4bb838 100644 --- a/fs/read_write.c +++ b/fs/read_write.c @@ -2081,3 +2081,27 @@ int vfs_dedupe_file_range(struct file *file, struct file_dedupe_range *same) return ret; } EXPORT_SYMBOL(vfs_dedupe_file_range); + +/** + * vfs_gethash - obtain a file's hash + * @file: file structure in question + * @hash_algo: the hash algorithm requested + * @buf: buffer to return the hash in + * @size: size allocated for the buffer by the caller + * + * This function allows filesystems that support securely storing the hash + * of a file to return it rather than forcing the kernel to recalculate it. + * Filesystems that cannot provide guarantees about the hash being resistant + * to offline attack should not implement this functionality. + * + * Returns 0 on success, -EOPNOTSUPP if the filesystem doesn't support it. + */ +int vfs_get_hash(struct file *file, enum hash_algo hash, uint8_t *buf, + size_t size) +{ + if (!file->f_op->get_hash) + return -EOPNOTSUPP; + + return file->f_op->get_hash(file, hash, buf, size); +} +EXPORT_SYMBOL(vfs_get_hash); diff --git a/include/linux/fs.h b/include/linux/fs.h index 6c0b4a1c22ff..540316cfd461 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -40,6 +40,7 @@ #include #include +#include struct backing_dev_info; struct bdi_writeback; @@ -1764,6 +1765,8 @@ struct file_operations { int (*dedupe_file_range)(struct file *, loff_t, struct file *, loff_t, u64); int (*fadvise)(struct file *, loff_t, loff_t, int); + int (*get_hash)(struct file *, enum hash_algo hash, uint8_t *buf, + size_t size); } __randomize_layout; struct inode_operations { @@ -1838,7 +1841,8 @@ extern int vfs_dedupe_file_range(struct file *file, extern int vfs_dedupe_file_range_one(struct file *src_file, loff_t src_pos, struct file *dst_file, loff_t dst_pos, u64 len); - +extern int vfs_get_hash(struct file *file, enum hash_algo hash, uint8_t *buf, + size_t size); struct super_operations { struct inode *(*alloc_inode)(struct super_block *sb); From patchwork Thu Oct 4 20:30:06 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matthew Garrett X-Patchwork-Id: 10626667 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id D5286184E for ; Thu, 4 Oct 2018 20:30:17 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C97912972D for ; Thu, 4 Oct 2018 20:30:17 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id BD4AF2972F; Thu, 4 Oct 2018 20:30:17 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.5 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI, USER_IN_DEF_DKIM_WL autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 4D34129733 for ; Thu, 4 Oct 2018 20:30:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727814AbeJEDZK (ORCPT ); Thu, 4 Oct 2018 23:25:10 -0400 Received: from mail-ot1-f73.google.com ([209.85.210.73]:48505 "EHLO mail-ot1-f73.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727802AbeJEDZK (ORCPT ); Thu, 4 Oct 2018 23:25:10 -0400 Received: by mail-ot1-f73.google.com with SMTP id e38-v6so7397582otj.15 for ; Thu, 04 Oct 2018 13:30:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=AtKf9yIc0wA5rkRTA/NVZYjgYNkLOigp5y5Pl1jWu4Y=; b=g9967gd7mKGrmY9zgYvlmNUijuisK9xsWEeapuC6BeONWUiaMCb7BvWdUEkkdPD0AM /1s4+eupL8WDfC4mhpjVxOu83ckLATkJexYRRX+X2u5Wc26se+nFXNCY8hZqYb0LHUam Q0n9zS5mq1pgklNprNTY3TyUxsbK8vMwfWzru7kKxfX7dMXiwTdXrDhqsNKovThzEIfF oVcVLGlSbxZGqn4pNsSX1YENUKiHcPruehsobuaeTu88x/z70NqlnPomypJB/FPZ6VNr ityTVhFC0h2SlSzsXBFRHCyUiPG1byFv9SNwUeOG1zUJIxBE/ysnZB71a4iCGPxEwOzn iwmw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=AtKf9yIc0wA5rkRTA/NVZYjgYNkLOigp5y5Pl1jWu4Y=; b=KYGedP8kQI6UM29bYl8mVO8rPsMTnP713vxH8HdLhAmNvZOe6kaoGEHoaGDCGcigE4 6rQlbYXraxGqxIA5I/WS04nijAj6aNZKCSS6yM0jSHF83PVIyq07KlEky7UjWHotVYiB xV+9bMDj/KQVusR88ICIuPDqc5/OhCCgNUS0W2ZGwu5Jffh9h1ophNEWaRFifRQMO8RA l4UH5wtOyNwH5EFa7+oTkGQTH1EwFfhJrZpkbqGkucatlfPZCPCEc7QanWjwah0qzRJa h/o8J0XUGHaX2J3/no/cDKUKZNdpA8ZbvSlUq797a+Zp8ltPTqsVUnh/W4g/hdXo3D58 4+hw== X-Gm-Message-State: ABuFfohOyy7bHZ3IQJVGpnSagt2ocCNaIJ1Of0GH7hX6wxO8jokHj3z7 PBxbLEvGxGjgnJRVcOPFc6tW5QfkjYpdUb34J9t9tA== X-Google-Smtp-Source: ACcGV62jtqbQKUewRBbQ1LdzCca4Dj9Q/q/n8Pu7bDLQXyC3o+9qG0owMvBh7DPteOm6a7LQbNFJN+l3g8cnNOWq0kc7vg== X-Received: by 2002:aca:3844:: with SMTP id f65-v6mr5869643oia.54.1538685015482; Thu, 04 Oct 2018 13:30:15 -0700 (PDT) Date: Thu, 4 Oct 2018 13:30:06 -0700 In-Reply-To: <20181004203007.217320-1-mjg59@google.com> Message-Id: <20181004203007.217320-3-mjg59@google.com> Mime-Version: 1.0 References: <20181004203007.217320-1-mjg59@google.com> X-Mailer: git-send-email 2.19.0.605.g01d371f741-goog Subject: [PATCH 2/3] IMA: Make use of filesystem-provided hashes From: Matthew Garrett To: linux-integrity@vger.kernel.org Cc: zohar@linux.vnet.ibm.com, dmitry.kasatkin@gmail.com, miklos@szeredi.hu, linux-fsdevel@vger.kernel.org, viro@zeniv.linux.org.uk, Matthew Garrett Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Some filesystems may be able to provide hashes in an out of band manner, and allowing them to do so is a performance win. This is especially true of FUSE-based filesystems where otherwise we recalculate the hash on every measurement. Make use of this by default, but provide a parameter to force recalculation rather than trusting the filesystem. Signed-off-by: Matthew Garrett --- Documentation/admin-guide/kernel-parameters.txt | 5 +++++ security/integrity/ima/ima_crypto.c | 11 +++++++++++ 2 files changed, 16 insertions(+) diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt index 92eb1f42240d..617ae0f83b14 100644 --- a/Documentation/admin-guide/kernel-parameters.txt +++ b/Documentation/admin-guide/kernel-parameters.txt @@ -1612,6 +1612,11 @@ different crypto accelerators. This option can be used to achieve best performance for particular HW. + ima.force_hash= [IMA] Force hash calculation in IMA + Format: + Always calculate hashes rather than trusting the + filesystem to provide them to us. + init= [KNL] Format: Run specified binary instead of /sbin/init as init diff --git a/security/integrity/ima/ima_crypto.c b/security/integrity/ima/ima_crypto.c index 7e7e7e7c250a..f25259b2b6ec 100644 --- a/security/integrity/ima/ima_crypto.c +++ b/security/integrity/ima/ima_crypto.c @@ -32,6 +32,10 @@ static unsigned long ima_ahash_minsize; module_param_named(ahash_minsize, ima_ahash_minsize, ulong, 0644); MODULE_PARM_DESC(ahash_minsize, "Minimum file size for ahash use"); +static bool ima_force_hash; +module_param_named(force_hash, ima_force_hash, bool_enable_only, 0644); +MODULE_PARM_DESC(force_hash, "Always calculate hashes"); + /* default is 0 - 1 page. */ static int ima_maxorder; static unsigned int ima_bufsize = PAGE_SIZE; @@ -431,6 +435,13 @@ int ima_calc_file_hash(struct file *file, struct ima_digest_data *hash) return -EINVAL; } + if (!ima_force_hash) { + hash->length = hash_digest_size[hash->algo]; + rc = vfs_get_hash(file, hash->algo, hash->digest, hash->length); + if (!rc) + return 0; + } + i_size = i_size_read(file_inode(file)); if (ima_ahash_minsize && i_size >= ima_ahash_minsize) { From patchwork Thu Oct 4 20:30:07 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matthew Garrett X-Patchwork-Id: 10626669 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 70E02174A for ; Thu, 4 Oct 2018 20:30:20 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 657652972D for ; Thu, 4 Oct 2018 20:30:20 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 59A9829733; Thu, 4 Oct 2018 20:30:20 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.5 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI, USER_IN_DEF_DKIM_WL autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id CB9392972D for ; Thu, 4 Oct 2018 20:30:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727838AbeJEDZN (ORCPT ); Thu, 4 Oct 2018 23:25:13 -0400 Received: from mail-it1-f201.google.com ([209.85.166.201]:55338 "EHLO mail-it1-f201.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727816AbeJEDZN (ORCPT ); Thu, 4 Oct 2018 23:25:13 -0400 Received: by mail-it1-f201.google.com with SMTP id m123-v6so12058868ith.5 for ; Thu, 04 Oct 2018 13:30:18 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=REUtv0qgnNOJHNLh3TngPvHaUsPHUHQ8qCSeGAYRe5Q=; b=OYInwCD+fhZcwFPQZ1TKM4qq64ApRXm2m2eB2r9iATpiVTRwt5G1GASL2dAg/xcupQ BPOpArOWVOms1zbyz05wuGbOy2k/39pZGKV90Q/YeL96TEC/kx0ia7GZTq6m0jPwu3/F KesImTfCtzXi/DfxklSK27jIMmlBYIjctVpSL72vBXnGBbr+zpTXW6E/RfDNc+FDVVzD YZp6QZwrT1k9OM3ro6+EsRX3U7Xhv3w/9ex/spmB7zAd+KyuKhCTi0faAxC97sk2T8h3 tufq0WAj/n8bkh1u5pNuxlryoRCpsjKnP+XPaNzFyg1xsWXG1LwFAQ4jRMfKSeL9Sgrz tSTg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=REUtv0qgnNOJHNLh3TngPvHaUsPHUHQ8qCSeGAYRe5Q=; b=YTCP6DdialRSbl3Ie0gFOhJVBgbP9kzuJvnSfd5QxYAU5Z7hkA6QIwa14lglQ+Lg5w IaTVQhmF7ewRcwo2ixOBGv6sk2Vtq5Ikm5vxmaG2KfwnFX0aTmr88RqpUPAD48AEp1e0 yhCria1dtx2QcmRb0oujrmFQw8JJAk611FMvoaurL3nBV82iB1Z6pK9XOnjrzzBxjfdr VR47WCsEEelTsRlEuTDOaw++s5DZA/UZHDPyxnp5ff7zzuQbPmnay7E3s3GkNPgK/88H HlI1EQX4H8M8JMLY9ZeDB2DADvKp3m4taglw9ZpxxGsaJ+uHuahzH8cUgkozyv0WAt/J 70BA== X-Gm-Message-State: ABuFfohbr6GtJk5DW4c9sLEw3pF1ZmqsgB+maSar9zO9a38GYr3jLjeA oCi551zcP7d98f9k3SfLIOQQSRoDm9GAWcD+6up0Nw== X-Google-Smtp-Source: ACcGV61zI5ssjtOcBmCxpuZ+C2f1o3/4pgdjwjZD1iTIFQCkTSxCwy8Ymk2ioBWd2IwWTeANqP5XBPp3/DIcjO71MFJJiw== X-Received: by 2002:a05:660c:8d1:: with SMTP id g17mr6278553itl.1.1538685017874; Thu, 04 Oct 2018 13:30:17 -0700 (PDT) Date: Thu, 4 Oct 2018 13:30:07 -0700 In-Reply-To: <20181004203007.217320-1-mjg59@google.com> Message-Id: <20181004203007.217320-4-mjg59@google.com> Mime-Version: 1.0 References: <20181004203007.217320-1-mjg59@google.com> X-Mailer: git-send-email 2.19.0.605.g01d371f741-goog Subject: [PATCH 3/3] FUSE: Allow filesystems to provide gethash methods From: Matthew Garrett To: linux-integrity@vger.kernel.org Cc: zohar@linux.vnet.ibm.com, dmitry.kasatkin@gmail.com, miklos@szeredi.hu, linux-fsdevel@vger.kernel.org, viro@zeniv.linux.org.uk, Matthew Garrett Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP FUSE implementations may have a secure way to provide file hashes (eg, they're a front-end to a remote store that ties files to their hashes). Allow filesystems to expose this information, but require an option to be provided before it can be used. This is to avoid malicious users being able to mount an unprivileged FUSE filesystem that provides incorrect hashes. A sufficiently malicious FUSE filesystem may still simply swap out its contents after the hash has been obtained - this patchset does nothing to change that, and sysadmins should have appropriate policy in place to protect against that. Signed-off-by: Matthew Garrett --- fs/fuse/file.c | 35 +++++++++++++++++++++++++++++++++++ fs/fuse/fuse_i.h | 7 +++++++ fs/fuse/inode.c | 10 ++++++++++ include/uapi/linux/fuse.h | 6 ++++++ 4 files changed, 58 insertions(+) diff --git a/fs/fuse/file.c b/fs/fuse/file.c index 32d0b883e74f..0696671ea070 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -3011,6 +3011,39 @@ static long fuse_file_fallocate(struct file *file, int mode, loff_t offset, return err; } + +static int fuse_file_get_hash(struct file *file, enum hash_algo hash, + uint8_t *buf, size_t size) +{ + struct fuse_file *ff = file->private_data; + struct fuse_conn *fc = ff->fc; + FUSE_ARGS(args); + struct fuse_gethash_in inarg; + int err = 0; + + if (!fc->allow_gethash) + return -EOPNOTSUPP; + + memset(&inarg, 0, sizeof(inarg)); + inarg.size = size; + inarg.hash = hash; + args.in.h.opcode = FUSE_GETHASH; + args.in.h.nodeid = ff->nodeid; + args.in.numargs = 1; + args.in.args[0].size = sizeof(inarg); + args.in.args[0].value = &inarg; + args.out.numargs = 1; + args.out.args[0].size = size; + args.out.args[0].value = buf; + + err = fuse_simple_request(fc, &args); + + if (err == -ENOSYS) + err = -EOPNOTSUPP; + + return err; +} + static const struct file_operations fuse_file_operations = { .llseek = fuse_file_llseek, .read_iter = fuse_file_read_iter, @@ -3027,6 +3060,7 @@ static const struct file_operations fuse_file_operations = { .compat_ioctl = fuse_file_compat_ioctl, .poll = fuse_file_poll, .fallocate = fuse_file_fallocate, + .get_hash = fuse_file_get_hash, }; static const struct file_operations fuse_direct_io_file_operations = { @@ -3044,6 +3078,7 @@ static const struct file_operations fuse_direct_io_file_operations = { .compat_ioctl = fuse_file_compat_ioctl, .poll = fuse_file_poll, .fallocate = fuse_file_fallocate, + .get_hash = fuse_file_get_hash, /* no splice_read */ }; diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index f78e9614bb5f..b4d4736cbb38 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h @@ -637,6 +637,13 @@ struct fuse_conn { /** Allow other than the mounter user to access the filesystem ? */ unsigned allow_other:1; + /* + * Allow the underlying filesystem to the hash of a file. This is + * used by IMA to avoid needing to calculate the hash on every + * measurement + */ + unsigned allow_gethash:1; + /** The number of requests waiting for completion */ atomic_t num_waiting; diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index db9e60b7eb69..8051506d245f 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c @@ -70,6 +70,7 @@ struct fuse_mount_data { unsigned group_id_present:1; unsigned default_permissions:1; unsigned allow_other:1; + unsigned allow_gethash:1; unsigned max_read; unsigned blksize; }; @@ -454,6 +455,7 @@ enum { OPT_ALLOW_OTHER, OPT_MAX_READ, OPT_BLKSIZE, + OPT_ALLOW_GETHASH, OPT_ERR }; @@ -466,6 +468,7 @@ static const match_table_t tokens = { {OPT_ALLOW_OTHER, "allow_other"}, {OPT_MAX_READ, "max_read=%u"}, {OPT_BLKSIZE, "blksize=%u"}, + {OPT_ALLOW_GETHASH, "allow_gethash"}, {OPT_ERR, NULL} }; @@ -552,6 +555,10 @@ static int parse_fuse_opt(char *opt, struct fuse_mount_data *d, int is_bdev, d->blksize = value; break; + case OPT_ALLOW_GETHASH: + d->allow_gethash = 1; + break; + default: return 0; } @@ -575,6 +582,8 @@ static int fuse_show_options(struct seq_file *m, struct dentry *root) seq_puts(m, ",default_permissions"); if (fc->allow_other) seq_puts(m, ",allow_other"); + if (fc->allow_gethash) + seq_puts(m, ",allow_gethash"); if (fc->max_read != ~0) seq_printf(m, ",max_read=%u", fc->max_read); if (sb->s_bdev && sb->s_blocksize != FUSE_DEFAULT_BLKSIZE) @@ -1141,6 +1150,7 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent) fc->user_id = d.user_id; fc->group_id = d.group_id; fc->max_read = max_t(unsigned, 4096, d.max_read); + fc->allow_gethash = d.allow_gethash; /* Used by get_root_inode() */ sb->s_fs_info = fc; diff --git a/include/uapi/linux/fuse.h b/include/uapi/linux/fuse.h index 92fa24c24c92..a43e80ea675d 100644 --- a/include/uapi/linux/fuse.h +++ b/include/uapi/linux/fuse.h @@ -381,6 +381,7 @@ enum fuse_opcode { FUSE_READDIRPLUS = 44, FUSE_RENAME2 = 45, FUSE_LSEEK = 46, + FUSE_GETHASH = 47, /* CUSE specific operations */ CUSE_INIT = 4096, @@ -792,4 +793,9 @@ struct fuse_lseek_out { uint64_t offset; }; +struct fuse_gethash_in { + uint32_t size; + uint32_t hash; +}; + #endif /* _LINUX_FUSE_H */