From patchwork Tue May 1 17:51:24 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matthew Garrett X-Patchwork-Id: 10374261 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id E74AC60384 for ; Tue, 1 May 2018 17:51:37 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id D830C28D13 for ; Tue, 1 May 2018 17:51:37 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id CCD8D28D18; Tue, 1 May 2018 17:51:37 +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 980B328D13 for ; Tue, 1 May 2018 17:51:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756032AbeEARvg (ORCPT ); Tue, 1 May 2018 13:51:36 -0400 Received: from mail-it0-f74.google.com ([209.85.214.74]:57206 "EHLO mail-it0-f74.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755898AbeEARvf (ORCPT ); Tue, 1 May 2018 13:51:35 -0400 Received: by mail-it0-f74.google.com with SMTP id 6-v6so10903297itl.6 for ; Tue, 01 May 2018 10:51:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=mime-version:date:in-reply-to:message-id:references:subject:from:to :cc; bh=6yZAEDTjVA6+1UsUiERlb6R2/EAmzLhyFyIfUi0ciy0=; b=Z0+AJX2dUnsY1VynEnkG4hldR/u7061XAV+y4nM0fdC8a6KHQISjUe5QQB2nhulYLD VcNFsSx71EJxvpOyCKmCyajWDXXM48Mz0mPmwIEFib+xBA/HS4180zDjljKZQkk012y+ pEchlOP3XZvq4K3iKsvtM4w04FlXNv7piOaNFAnc788peD74iuJMnBI137PZDWz6vjUx 67//sTda9cWvx6dKE4i7gK/UA1bdVC/cjb3lMrn/ir6mBdHxvzIusPslUJmLTHyVbRnN hiikPXYUCLUozUU7iPrIF3KDROuFVjRhNhrqgNpOPFu7HDb+G8n0zRXD+aUN2yVW8NO+ pfsA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:date:in-reply-to:message-id :references:subject:from:to:cc; bh=6yZAEDTjVA6+1UsUiERlb6R2/EAmzLhyFyIfUi0ciy0=; b=OsmJwXMEpX8d+MIP+hJUp0BrPojLPCQ0KKLHLD/hB1GNtHYCqh0eCpueALfsDws7m0 EhBc9bfvcVoRMJGlRQppn/xETSXgjixG0TwbuLKzPjHHHnOlLJWXHoXkudejM9F9EhJl O/pttqN+bJY5XbDtyvsOrmBAUSzYJxdsDvUVHsy/JfNkgm6mOgZA1DKjaZMB8oEdIWNE /lYs6Ud0LOjo7+alNAYhbdkinIS/8ooh33aB5C++wAiwZj/PlCxni/MQFYQfPATG9oEH ++60opQyLuq6cGwiX+DD42AniI+JUVOLNesO0cN5tiMcgh86IsQVnQk2wjblpUVazM4/ eZDw== X-Gm-Message-State: ALQs6tBGUcRWw7gaDYUH51PnV0R/MJM3ovbYdISfbCOm2pH+dwVA+2Qa Ca2EOaN6hKo8EQa0/UFesftjrZMnVIXXcz7s5ZxW56dbX5+DVGEUS25RD87FzSrEykSGu9S4RMq 5vC722+Sq+vU+ZZSsMzgv9pH+fOpAnHeteXs= X-Google-Smtp-Source: AB8JxZpMdSG02S7E2rb+tycIbAgwEWLgALxRH+jVFOWDHk0Ba7tT4+qF15i8jiJoJNjZp4QK5yL3c34nkQcz1seO+tYjyA== MIME-Version: 1.0 X-Received: by 2002:a24:7f42:: with SMTP id r63-v6mr9141382itc.9.1525197094978; Tue, 01 May 2018 10:51:34 -0700 (PDT) Date: Tue, 1 May 2018 10:51:24 -0700 In-Reply-To: <20180501175124.192587-1-mjg59@google.com> Message-Id: <20180501175124.192587-2-mjg59@google.com> References: <20180501175124.192587-1-mjg59@google.com> X-Mailer: git-send-email 2.17.0.441.gb46fe60e1d-goog Subject: [PATCH V3 2/2] EVM: Allow runtime modification of the set of verified xattrs From: Matthew Garrett To: linux-integrity@vger.kernel.org Cc: zohar@linux.vnet.ibm.com, Matthew Garrett Sender: linux-integrity-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-integrity@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Sites may wish to provide additional metadata alongside files in order to make more fine-grained security decisions[1]. The security of this is enhanced if this metadata is protected, something that EVM makes possible. However, the kernel cannot know about the set of extended attributes that local admins may wish to protect, and hardcoding this policy in the kernel makes it difficult to change over time and less convenient for distributions to enable. This patch adds a new /sys/kernel/security/evm_xattrs node, which can be read to obtain the current set of EVM-protected extended attributes or written to in order to add new entries. Extending this list will not change the validity of any existing signatures provided that the file in question does not have any of the additional extended attributes - missing xattrs are skipped when calculating the EVM hash. [1] For instance, a package manager could install information about the package uploader in an additional extended attribute. Local LSM policy could then be associated with that extended attribute in order to restrict the privileges available to packages from less trusted uploaders. Signed-off-by: Matthew Garrett --- Documentation/ABI/testing/evm | 13 ++++ security/integrity/evm/evm_secfs.c | 102 +++++++++++++++++++++++++++-- 2 files changed, 109 insertions(+), 6 deletions(-) diff --git a/Documentation/ABI/testing/evm b/Documentation/ABI/testing/evm index d12cb2eae9ee..bfe529eb26b2 100644 --- a/Documentation/ABI/testing/evm +++ b/Documentation/ABI/testing/evm @@ -57,3 +57,16 @@ Description: dracut (via 97masterkey and 98integrity) and systemd (via core/ima-setup) have support for loading keys at boot time. + +What: security/evm_xattrs +Date: April 2018 +Contact: Matthew Garrett +Description: + Shows the set of extended attributes used to calculate or + validate the EVM signature, and allows additional attributes + to be added at runtime. Adding additional extended attributes + will result in any existing signatures generated without the + additional attributes becoming invalid, and any signatures + generated after additional attributes are added will only be + valid if the same additional attributes are configured on + system boot. diff --git a/security/integrity/evm/evm_secfs.c b/security/integrity/evm/evm_secfs.c index feba03bbedae..3b371125d439 100644 --- a/security/integrity/evm/evm_secfs.c +++ b/security/integrity/evm/evm_secfs.c @@ -20,6 +20,7 @@ #include "evm.h" static struct dentry *evm_init_tpm; +static struct dentry *evm_xattrs; /** * evm_read_key - read() for /evm @@ -107,13 +108,102 @@ static const struct file_operations evm_key_ops = { .write = evm_write_key, }; -int __init evm_init_secfs(void) +/** + * evm_read_xattrs - read() for /evm_xattrs + * + * @filp: file pointer, not actually used + * @buf: where to put the result + * @count: maximum to send along + * @ppos: where to start + * + * Returns number of bytes read or error code, as appropriate + */ +static ssize_t evm_read_xattrs(struct file *filp, char __user *buf, + size_t count, loff_t *ppos) { - int error = 0; + char *temp; + int offset = 0; + ssize_t rc, size = 0; + struct xattr_list *xattr; + + if (*ppos != 0) + return 0; - evm_init_tpm = securityfs_create_file("evm", S_IRUSR | S_IRGRP, - NULL, NULL, &evm_key_ops); + list_for_each_entry(xattr, &evm_config_xattrnames, list) + size += strlen(xattr->name) + 1; + + temp = kmalloc(size + 1, GFP_KERNEL); + if (!temp) + return -ENOMEM; + + list_for_each_entry(xattr, &evm_config_xattrnames, list) { + sprintf(temp + offset, "%s\n", xattr->name); + offset += strlen(xattr->name) + 1; + } + + rc = simple_read_from_buffer(buf, count, ppos, temp, strlen(temp)); + + return rc; +} + +/** + * evm_write_xattrs - write() for /evm_xattrs + * @file: file pointer, not actually used + * @buf: where to get the data from + * @count: bytes sent + * @ppos: where to start + * + * Returns number of bytes written or error code, as appropriate + */ +static ssize_t evm_write_xattrs(struct file *file, const char __user *buf, + size_t count, loff_t *ppos) +{ + int len; + struct xattr_list *xattr; + + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + + if (*ppos != 0) + return -EINVAL; + + xattr = kmalloc(sizeof(struct xattr_list), GFP_KERNEL); + if (!xattr) + return -ENOMEM; + + xattr->name = memdup_user_nul(buf, count); + if (!xattr->name) { + kfree(xattr); + return -ENOMEM; + } + + /* Remove any trailing newline */ + len = strlen(xattr->name); + if (xattr->name[len-1] == '\n') + xattr->name[len-1] = '\0'; + + list_add_tail(&xattr->list, &evm_config_xattrnames); + return count; +} + +static const struct file_operations evm_xattr_ops = { + .read = evm_read_xattrs, + .write = evm_write_xattrs, +}; + +int __init evm_init_secfs(void) +{ + evm_init_tpm = securityfs_create_file("evm", 0440, NULL, NULL, + &evm_key_ops); if (!evm_init_tpm || IS_ERR(evm_init_tpm)) - error = -EFAULT; - return error; + return -EFAULT; + + evm_xattrs = securityfs_create_file("evm_xattrs", 0440, NULL, NULL, + &evm_xattr_ops); + if (!evm_xattrs || IS_ERR(evm_xattrs)) { + securityfs_remove(evm_init_tpm); + return -EFAULT; + } + + return 0; }