From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 25BC5C433FE for ; Wed, 13 Oct 2021 19:32:55 +0000 (UTC) Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [216.205.24.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id A93E061163 for ; Wed, 13 Oct 2021 19:32:54 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org A93E061163 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linux.microsoft.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=redhat.com Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-311-_bawC13_NsmfYVKHnZgfKQ-1; Wed, 13 Oct 2021 15:32:50 -0400 X-MC-Unique: _bawC13_NsmfYVKHnZgfKQ-1 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 226DA8042BD; Wed, 13 Oct 2021 19:32:47 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.20]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 0BE4B5C1CF; Wed, 13 Oct 2021 19:32:47 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id DBF601800FE4; Wed, 13 Oct 2021 19:32:46 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.rdu2.redhat.com [10.11.54.3]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id 19DJD1Ll018689 for ; Wed, 13 Oct 2021 15:13:01 -0400 Received: by smtp.corp.redhat.com (Postfix) id DABD41000DBC; Wed, 13 Oct 2021 19:13:00 +0000 (UTC) Received: from mimecast-mx02.redhat.com (mimecast02.extmail.prod.ext.rdu2.redhat.com [10.11.55.18]) by smtp.corp.redhat.com (Postfix) with ESMTPS id D5B2B11457FD for ; Wed, 13 Oct 2021 19:12:56 +0000 (UTC) Received: from us-smtp-1.mimecast.com (us-smtp-delivery-1.mimecast.com [207.211.31.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 4FA6B800186 for ; Wed, 13 Oct 2021 19:12:56 +0000 (UTC) Received: from linux.microsoft.com (linux.microsoft.com [13.77.154.182]) by relay.mimecast.com with ESMTP id us-mta-465-ccqkjPN8M8y246JyEyjmWg-1; Wed, 13 Oct 2021 15:12:54 -0400 X-MC-Unique: ccqkjPN8M8y246JyEyjmWg-1 Received: from linuxonhyperv3.guj3yctzbm1etfxqx2vob5hsef.xx.internal.cloudapp.net (linux.microsoft.com [13.77.154.182]) by linux.microsoft.com (Postfix) with ESMTPSA id 98A7D20B9D0A; Wed, 13 Oct 2021 12:06:40 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 98A7D20B9D0A From: deven.desai@linux.microsoft.com To: corbet@lwn.net, axboe@kernel.dk, agk@redhat.com, snitzer@redhat.com, ebiggers@kernel.org, tytso@mit.edu, paul@paul-moore.com, eparis@redhat.com, jmorris@namei.org, serge@hallyn.com Subject: [RFC PATCH v7 14/16] scripts: add boot policy generation program Date: Wed, 13 Oct 2021 12:06:33 -0700 Message-Id: <1634151995-16266-15-git-send-email-deven.desai@linux.microsoft.com> In-Reply-To: <1634151995-16266-1-git-send-email-deven.desai@linux.microsoft.com> References: <1634151995-16266-1-git-send-email-deven.desai@linux.microsoft.com> X-Mimecast-Impersonation-Protect: Policy=CLT - Impersonation Protection Definition; Similar Internal Domain=false; Similar Monitored External Domain=false; Custom External Domain=false; Mimecast External Domain=false; Newly Observed Domain=false; Internal User Name=false; Custom Display Name List=false; Reply-to Address Mismatch=false; Targeted Threat Dictionary=false; Mimecast Threat Dictionary=false; Custom Threat Dictionary=false X-Scanned-By: MIMEDefang 2.78 on 10.11.54.3 X-loop: linux-audit@redhat.com X-Mailman-Approved-At: Wed, 13 Oct 2021 15:26:43 -0400 Cc: linux-security-module@vger.kernel.org, linux-doc@vger.kernel.org, jannh@google.com, linux-fscrypt@vger.kernel.org, linux-kernel@vger.kernel.org, linux-block@vger.kernel.org, dm-devel@redhat.com, linux-audit@redhat.com X-BeenThere: linux-audit@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Linux Audit Discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: linux-audit-bounces@redhat.com Errors-To: linux-audit-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=linux-audit-bounces@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit From: Deven Bowers Enables an IPE policy to be enforced from kernel start, enabling access control based on trust from kernel startup. This is accomplished by transforming an IPE policy indicated by CONFIG_IPE_BOOT_POLICY into a c-string literal that is parsed at kernel startup as an unsigned policy. Signed-off-by: Deven Bowers --- Relevant changes since v6: * Move patch 01/12 to [14/16] of the series --- MAINTAINERS | 1 + scripts/Makefile | 1 + scripts/ipe/Makefile | 2 + scripts/ipe/polgen/.gitignore | 1 + scripts/ipe/polgen/Makefile | 6 ++ scripts/ipe/polgen/polgen.c | 145 ++++++++++++++++++++++++++++++++++ security/ipe/.gitignore | 1 + security/ipe/Kconfig | 10 +++ security/ipe/Makefile | 13 +++ security/ipe/ctx.c | 18 +++++ 10 files changed, 198 insertions(+) create mode 100644 scripts/ipe/Makefile create mode 100644 scripts/ipe/polgen/.gitignore create mode 100644 scripts/ipe/polgen/Makefile create mode 100644 scripts/ipe/polgen/polgen.c create mode 100644 security/ipe/.gitignore diff --git a/MAINTAINERS b/MAINTAINERS index f1e76f791d47..a84ca781199b 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -9283,6 +9283,7 @@ INTEGRITY POLICY ENFORCEMENT (IPE) M: Deven Bowers M: Fan Wu S: Supported +F: scripts/ipe/ F: security/ipe/ INTEL 810/815 FRAMEBUFFER DRIVER diff --git a/scripts/Makefile b/scripts/Makefile index 9adb6d247818..a31da6d57a36 100644 --- a/scripts/Makefile +++ b/scripts/Makefile @@ -41,6 +41,7 @@ targets += module.lds subdir-$(CONFIG_GCC_PLUGINS) += gcc-plugins subdir-$(CONFIG_MODVERSIONS) += genksyms subdir-$(CONFIG_SECURITY_SELINUX) += selinux +subdir-$(CONFIG_SECURITY_IPE) += ipe # Let clean descend into subdirs subdir- += basic dtc gdb kconfig mod diff --git a/scripts/ipe/Makefile b/scripts/ipe/Makefile new file mode 100644 index 000000000000..e87553fbb8d6 --- /dev/null +++ b/scripts/ipe/Makefile @@ -0,0 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0-only +subdir-y := polgen diff --git a/scripts/ipe/polgen/.gitignore b/scripts/ipe/polgen/.gitignore new file mode 100644 index 000000000000..80f32f25d200 --- /dev/null +++ b/scripts/ipe/polgen/.gitignore @@ -0,0 +1 @@ +polgen diff --git a/scripts/ipe/polgen/Makefile b/scripts/ipe/polgen/Makefile new file mode 100644 index 000000000000..066060c22b4a --- /dev/null +++ b/scripts/ipe/polgen/Makefile @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: GPL-2.0 +hostprogs-always-y := polgen +HOST_EXTRACFLAGS += \ + -I$(srctree)/include \ + -I$(srctree)/include/uapi \ + diff --git a/scripts/ipe/polgen/polgen.c b/scripts/ipe/polgen/polgen.c new file mode 100644 index 000000000000..73cf13e743f7 --- /dev/null +++ b/scripts/ipe/polgen/polgen.c @@ -0,0 +1,145 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) Microsoft Corporation. All rights reserved. + */ + +#include +#include +#include +#include +#include + +static void usage(const char *const name) +{ + printf("Usage: %s OutputFile (PolicyFile)\n", name); + exit(EINVAL); +} + +static int policy_to_buffer(const char *pathname, char **buffer, size_t *size) +{ + int rc = 0; + FILE *fd; + char *lbuf; + size_t fsize; + size_t read; + + fd = fopen(pathname, "r"); + if (!fd) { + rc = errno; + goto out; + } + + fseek(fd, 0, SEEK_END); + fsize = ftell(fd); + rewind(fd); + + lbuf = malloc(fsize); + if (!lbuf) { + rc = ENOMEM; + goto out_close; + } + + read = fread((void *)lbuf, sizeof(*lbuf), fsize, fd); + if (read != fsize) { + rc = -1; + goto out_free; + } + + *buffer = lbuf; + *size = fsize; + fclose(fd); + + return rc; + +out_free: + free(lbuf); +out_close: + fclose(fd); +out: + return rc; +} + +static int write_boot_policy(const char *pathname, const char *buf, size_t size) +{ + int rc = 0; + FILE *fd; + size_t i; + + fd = fopen(pathname, "w"); + if (!fd) { + rc = errno; + goto err; + } + + fprintf(fd, "/* This file is automatically generated."); + fprintf(fd, " Do not edit. */\n"); + fprintf(fd, "#include \n"); + fprintf(fd, "\nextern const char *const ipe_boot_policy;\n\n"); + fprintf(fd, "const char *const ipe_boot_policy =\n"); + + if (!buf || size == 0) { + fprintf(fd, "\tNULL;\n"); + fclose(fd); + return 0; + } + + fprintf(fd, "\t\""); + + for (i = 0; i < size; ++i) { + switch (buf[i]) { + case '"': + fprintf(fd, "\\\""); + break; + case '\'': + fprintf(fd, "'"); + break; + case '\n': + fprintf(fd, "\\n\"\n\t\""); + break; + case '\\': + fprintf(fd, "\\\\"); + break; + case '\t': + fprintf(fd, "\\t"); + break; + case '\?': + fprintf(fd, "\\?"); + break; + default: + fprintf(fd, "%c", buf[i]); + } + } + fprintf(fd, "\";\n"); + fclose(fd); + + return 0; + +err: + if (fd) + fclose(fd); + return rc; +} + +int main(int argc, const char *const argv[]) +{ + int rc = 0; + size_t len = 0; + char *policy = NULL; + + if (argc < 2) + usage(argv[0]); + + if (argc > 2) { + rc = policy_to_buffer(argv[2], &policy, &len); + if (rc != 0) + goto cleanup; + } + + rc = write_boot_policy(argv[1], policy, len); +cleanup: + if (policy) + free(policy); + if (rc != 0) + perror("An error occurred during policy conversion: "); + return rc; +} diff --git a/security/ipe/.gitignore b/security/ipe/.gitignore new file mode 100644 index 000000000000..eca22ad5ed22 --- /dev/null +++ b/security/ipe/.gitignore @@ -0,0 +1 @@ +boot-policy.c \ No newline at end of file diff --git a/security/ipe/Kconfig b/security/ipe/Kconfig index fcf82a8152ec..39df680b67a2 100644 --- a/security/ipe/Kconfig +++ b/security/ipe/Kconfig @@ -20,6 +20,16 @@ menuconfig SECURITY_IPE if SECURITY_IPE +config IPE_BOOT_POLICY + string "Integrity policy to apply on system startup" + help + This option specifies a filepath to a IPE policy that is compiled + into the kernel. This policy will be enforced until a policy update + is deployed via the $securityfs/ipe/policies/$policy_name/active + interface. + + If unsure, leave blank. + choice prompt "Hash algorithm used in auditing policies" default IPE_AUDIT_HASH_SHA1 diff --git a/security/ipe/Makefile b/security/ipe/Makefile index 1e7b2d7fcd9e..89fec670f954 100644 --- a/security/ipe/Makefile +++ b/security/ipe/Makefile @@ -7,7 +7,18 @@ ccflags-y := -I$(srctree)/security/ipe/modules +quiet_cmd_polgen = IPE_POL $(2) + cmd_polgen = scripts/ipe/polgen/polgen security/ipe/boot-policy.c $(2) + +$(eval $(call config_filename,IPE_BOOT_POLICY)) + +targets += boot-policy.c + +$(obj)/boot-policy.c: scripts/ipe/polgen/polgen $(IPE_BOOT_POLICY_FILENAME) FORCE + $(call if_changed,polgen,$(IPE_BOOT_POLICY_FILENAME)) + obj-$(CONFIG_SECURITY_IPE) += \ + boot-policy.o \ ctx.o \ eval.o \ fs.o \ @@ -21,3 +32,5 @@ obj-$(CONFIG_SECURITY_IPE) += \ policyfs.o \ obj-$(CONFIG_AUDIT) += audit.o + +clean-files := boot-policy.c \ diff --git a/security/ipe/ctx.c b/security/ipe/ctx.c index fc9b8e467bc9..879acf4ceac5 100644 --- a/security/ipe/ctx.c +++ b/security/ipe/ctx.c @@ -15,6 +15,7 @@ #include #include +extern const char *const ipe_boot_policy; static bool success_audit; static bool enforce = true; @@ -329,6 +330,7 @@ void ipe_put_ctx(struct ipe_context *ctx) int __init ipe_init_ctx(void) { int rc = 0; + struct ipe_policy *p = NULL; struct ipe_context *lns = NULL; lns = create_ctx(); @@ -342,10 +344,26 @@ int __init ipe_init_ctx(void) WRITE_ONCE(lns->enforce, enforce); spin_unlock(&lns->lock); + if (ipe_boot_policy) { + p = ipe_new_policy(ipe_boot_policy, strlen(ipe_boot_policy), + NULL, 0); + if (IS_ERR(p)) { + rc = PTR_ERR(lns); + goto err; + } + + ipe_add_policy(lns, p); + rc = ipe_set_active_pol(p); + if (!rc) + goto err; + } + rcu_assign_pointer(*ipe_tsk_ctx(current), lns); + ipe_put_policy(p); return 0; err: + ipe_put_policy(p); ipe_put_ctx(lns); return rc; } -- 2.33.0 -- Linux-audit mailing list Linux-audit@redhat.com https://listman.redhat.com/mailman/listinfo/linux-audit