Received: by 2002:a25:ab43:0:0:0:0:0 with SMTP id u61csp1149281ybi; Thu, 30 May 2019 12:23:44 -0700 (PDT) X-Google-Smtp-Source: APXvYqzswt4g91KOXPO0I4m3JjdpjmH+Qf90mnsVgXjv9kHyvAveayHtNNQFMEVt9Ql3eipuPzBG X-Received: by 2002:a17:90a:be0b:: with SMTP id a11mr5119946pjs.88.1559244224652; Thu, 30 May 2019 12:23:44 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1559244224; cv=none; d=google.com; s=arc-20160816; b=NxfOKFpuvwvnp3c6QhabExhX/cIFWz8TnEV+mgOmpnqHl7GUenlKwJGGv2omJQ2JR8 XLZIarE0iZNC1sl+oSblGvMIhkKQlA9vhhHDokNSvBTsVeHs+JuU/yWmx5R9pVbwwYGu kUB1S4v0G3twRyHb7zWoaM3chbGJo4oeGSSPqJy9JdU/GDuIR+Ry+I0Kh2UWc04Q3UZf aEmVyhCCrHVag6vNxXvoTQT3Jbe/JoUT1r4BxYboLAA+sqc2DZ62aXtbsDlyqqOlSqvZ 6KqQ1TDRX8o9XYI6JZL0sOMU2nBR2xSh4PfbK53vh/CvqlpgLWkIEa8zBLSBqdNp26US Wo7Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:cc:to:from:subject:references :mime-version:message-id:in-reply-to:date:dkim-signature; bh=KfHgTGg/JNwEVGFgmhHSyJz3/wBu2D+Qm1I3WpfuIqQ=; b=f7DRyVWjcJc6rQAEHlMFnpVndgBm1gkY78siriadp8rlIJSdy+VqoENMNyup6ccPg+ flga1Xu117Z1CNPq83YAV7Zr5C0cCda2D+ippPv6bynMKdoScVf4EOLa+W5J+B3JigHd kpIoj3SZiFAPES7BbuUO9ewA45gUSLBacbpZu7Mp1ub9itRlH2lDuY/R0uXhqD0mQXZn 9f1rWmUp93Nv2Et8gkuivx+9/dbMTUSN8MFqlEwS7xta4Ii0UtemjXjMObZaNhypa/sV 0eAFpywNUC7zzqYKckktlupaN+78Pt0gppzN5kiS/0k23raqIS4Fe+THBgU5xzoW6McP 4xNg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@google.com header.s=20161025 header.b="R0dkl/E3"; 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=REJECT sp=REJECT dis=NONE) header.from=google.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id x19si3271262pjq.79.2019.05.30.12.23.28; Thu, 30 May 2019 12:23:44 -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=@google.com header.s=20161025 header.b="R0dkl/E3"; 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=REJECT sp=REJECT dis=NONE) header.from=google.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1725961AbfE3TWQ (ORCPT + 99 others); Thu, 30 May 2019 15:22:16 -0400 Received: from mail-qt1-f201.google.com ([209.85.160.201]:32931 "EHLO mail-qt1-f201.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725897AbfE3TWP (ORCPT ); Thu, 30 May 2019 15:22:15 -0400 Received: by mail-qt1-f201.google.com with SMTP id r40so5871345qtk.0 for ; Thu, 30 May 2019 12:22:14 -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=KfHgTGg/JNwEVGFgmhHSyJz3/wBu2D+Qm1I3WpfuIqQ=; b=R0dkl/E3g/fEkV02Bx8k1+qVBP+rGhJ2PPH8UHVuKZnR2qC526HpFcoS5lEQDvsFwW F0kYkiOvskR4qdw8V9lDdfKO0yX5+AkcJeoORYcQ1T+zcSRL4d6DCrrU4gWj4O41HOOk N8jqjmD0KTjAHExyTgXSHtD5hL92FBUevn+NVCB56pLVtvKoCUDQjZDclnttOFjkRfV+ si6eLoc4SF7zXS0NtTu+7TzhxHCo/E51b7FG+MG/zm2y0RxOfIj46btBHlXonDja4Tbc 5uDHcmwgPD5WbuRmoeNAgnhB29jdFc3KzKSqUdrfS5kwDxGPPtGMoxhYxBbpqCtLrPQe yj4g== 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=KfHgTGg/JNwEVGFgmhHSyJz3/wBu2D+Qm1I3WpfuIqQ=; b=m6EDHjwUUuSpi3x2ZM8yYwWE+86vuOYVcjmB4CjWAq5vA/POwUHIVsztPavjzjXnAg AcRFzvljxGFrbsXEiCMXUI0Il7Ykw3hb0fwVpuXGTppAyXmimL0DgY06dFbFCdSaHi6v O+/ag1bCaA+KET0IAZJHlReUhBYtuec5xr/7Tav9U+r/etl7PbvlJPMJwYRO7dA8ve3V zRfEKzfKBgy4PIQHIwnw2xCOZcSuimIqCMGu4wuu1pwH5wJkD2w9k3aspaXtLde6Wxoc F1f8c018VqK7I2z4JCALN3D7DVCYQX75oFFClRcjY2L3E3xv7kjuxTIqwZEIXqaeS8bZ x2Tw== X-Gm-Message-State: APjAAAXnLls9bM7HG6iaT0eSEsB3wFXeZfgVrfkJnfcKoiO9flsXqXJM QHl5VGB0uMFKa6uK6ukN93afGyOZU8E= X-Received: by 2002:ac8:704:: with SMTP id g4mr5009978qth.207.1559244134330; Thu, 30 May 2019 12:22:14 -0700 (PDT) Date: Thu, 30 May 2019 12:22:08 -0700 In-Reply-To: <20190529224350.6460-1-mikewu@google.com> Message-Id: <20190530192208.99773-1-mikewu@google.com> Mime-Version: 1.0 References: <20190529224350.6460-1-mikewu@google.com> X-Mailer: git-send-email 2.22.0.rc1.257.g3120a18244-goog Subject: [PATCH v2] Allow to exclude specific file types in LoadPin From: Ke Wu To: Kees Cook , Jonathan Corbet , James Morris , "Serge E. Hallyn" Cc: linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-security-module@vger.kernel.org, Ke Wu Content-Type: text/plain; charset="UTF-8" Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Linux kernel already provide MODULE_SIG and KEXEC_VERIFY_SIG to make sure loaded kernel module and kernel image are trusted. This patch adds a kernel command line option "loadpin.exclude" which allows to exclude specific file types from LoadPin. This is useful when people want to use different mechanisms to verify module and kernel image while still use LoadPin to protect the integrity of other files kernel loads. Signed-off-by: Ke Wu --- Changelog since v1: - Mark ignore_read_file_id with __ro_after_init. - Mark parse_exclude() with __init. - Use ARRAY_SIZE(ignore_read_file_id) instead of READING_MAX_ID. Documentation/admin-guide/LSM/LoadPin.rst | 10 ++++++ security/loadpin/loadpin.c | 38 +++++++++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/Documentation/admin-guide/LSM/LoadPin.rst b/Documentation/admin-guide/LSM/LoadPin.rst index 32070762d24c..716ad9b23c9a 100644 --- a/Documentation/admin-guide/LSM/LoadPin.rst +++ b/Documentation/admin-guide/LSM/LoadPin.rst @@ -19,3 +19,13 @@ block device backing the filesystem is not read-only, a sysctl is created to toggle pinning: ``/proc/sys/kernel/loadpin/enabled``. (Having a mutable filesystem means pinning is mutable too, but having the sysctl allows for easy testing on systems with a mutable filesystem.) + +It's also possible to exclude specific file types from LoadPin using kernel +command line option "``loadpin.exclude``". By default, all files are +included, but they can be excluded using kernel command line option such +as "``loadpin.exclude=kernel-module,kexec-image``". This allows to use +different mechanisms such as ``CONFIG_MODULE_SIG`` and +``CONFIG_KEXEC_VERIFY_SIG`` to verify kernel module and kernel image while +still use LoadPin to protect the integrity of other files kernel loads. The +full list of valid file types can be found in ``kernel_read_file_str`` +defined in ``include/linux/fs.h``. diff --git a/security/loadpin/loadpin.c b/security/loadpin/loadpin.c index 055fb0a64169..d5f064644c54 100644 --- a/security/loadpin/loadpin.c +++ b/security/loadpin/loadpin.c @@ -45,6 +45,8 @@ static void report_load(const char *origin, struct file *file, char *operation) } static int enforce = IS_ENABLED(CONFIG_SECURITY_LOADPIN_ENFORCE); +static char *exclude_read_files[READING_MAX_ID]; +static int ignore_read_file_id[READING_MAX_ID] __ro_after_init; static struct super_block *pinned_root; static DEFINE_SPINLOCK(pinned_root_spinlock); @@ -129,6 +131,13 @@ static int loadpin_read_file(struct file *file, enum kernel_read_file_id id) struct super_block *load_root; const char *origin = kernel_read_file_id_str(id); + /* If the file id is excluded, ignore the pinning. */ + if ((unsigned int)id < ARRAY_SIZE(ignore_read_file_id) && + ignore_read_file_id[id]) { + report_load(origin, file, "pinning-excluded"); + return 0; + } + /* This handles the older init_module API that has a NULL file. */ if (!file) { if (!enforce) { @@ -187,10 +196,37 @@ static struct security_hook_list loadpin_hooks[] __lsm_ro_after_init = { LSM_HOOK_INIT(kernel_load_data, loadpin_load_data), }; +static void __init parse_exclude(void) +{ + int i, j; + char *cur; + + for (i = 0; i < ARRAY_SIZE(exclude_read_files); i++) { + cur = exclude_read_files[i]; + if (!cur) + break; + if (*cur == '\0') + continue; + + for (j = 0; j < ARRAY_SIZE(kernel_read_file_str); j++) { + if (strcmp(cur, kernel_read_file_str[j]) == 0) { + pr_info("excluding: %s\n", + kernel_read_file_str[j]); + ignore_read_file_id[j] = 1; + /* + * Can not break, because one read_file_str + * may map to more than on read_file_id. + */ + } + } + } +} + static int __init loadpin_init(void) { pr_info("ready to pin (currently %senforcing)\n", enforce ? "" : "not "); + parse_exclude(); security_add_hooks(loadpin_hooks, ARRAY_SIZE(loadpin_hooks), "loadpin"); return 0; } @@ -203,3 +239,5 @@ DEFINE_LSM(loadpin) = { /* Should not be mutable after boot, so not listed in sysfs (perm == 0). */ module_param(enforce, int, 0); MODULE_PARM_DESC(enforce, "Enforce module/firmware pinning"); +module_param_array_named(exclude, exclude_read_files, charp, NULL, 0); +MODULE_PARM_DESC(exclude, "Exclude pinning specific read file types"); -- 2.22.0.rc1.257.g3120a18244-goog