Received: by 2002:a05:6a10:5bc5:0:0:0:0 with SMTP id os5csp3752882pxb; Wed, 13 Oct 2021 12:12:28 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyONhsMdIbD+HAPdEc9ej/y19eA38h4YP6aDSaFLbjpb2oFCouZDNL1px3A1amEnYUZxxHg X-Received: by 2002:a17:906:c248:: with SMTP id bl8mr1217814ejb.360.1634152348240; Wed, 13 Oct 2021 12:12:28 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1634152348; cv=none; d=google.com; s=arc-20160816; b=SokTHbOZneCqHbrOUQ97+hIquhHEUz5ca9dvt2fvRsR1Qx7qx+Kb94Rx529MC25Rxp BgO639byPtvnfHKjaFNpfV4YA4f/EQljfxgC8hIurvMEaZs/niTBPD+cYUGQ7jY0sMGQ Dts9aokHoh3YfAHCfDQ8+zUuRwR249DvPjlXhxgFqxTSBTkGq7Q8imK+S0pVealH2kE4 ZeAP6/uLUKDmmHf4sX3Qs3F0/I+uD9sMfi4Q+GVn5LlArDNWGUmuQibZIzSTwnQMJdlK H6OVfaCWnuWgJf+88XptW/sckJZUQgRwR6lyQsZKHh4zVWrd+G3xH/p1NeQ97RtryBv0 Bm9Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:references:in-reply-to:message-id:date:subject :cc:to:from:dkim-signature:dkim-filter; bh=mStA1CiElH9sJhNsB0BIIO5Ubb1vgZLKd117rmoKAGc=; b=wCBzZ5r0/CQnJ62njN7UY+/t6TWxSZRCJpOIGHVOaNjGhF5VkR1V6N06/GHfWL89yJ yGVdRowmLHwgNo1YUjBD4jN3JmUFXNSe1f2pQ8DxCaOFsByWCHwdjXwfbHgrtMn+RJOP k+v4p7mXhV+TaplLfRT73ydFMxPThAIDkEsbU7SDFgWNI0MCOz7hs7Ljxm2Lo0AR4DvE NueQENESDLImBdjQPTp37YsCBoB6GbFOflHfTmGlBtKVh4zEDYvmK52GqzZ0HnIGGPZt LKxjExS9yj7Lp93u6eNlqZHPz4o+PybuwVyKRr9qetEDTrw5QGseqVb+L0tNzdnObkcx WY0A== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linux.microsoft.com header.s=default header.b=UEdAvs9P; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linux.microsoft.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id m4si450044edj.623.2021.10.13.12.12.04; Wed, 13 Oct 2021 12:12:28 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linux.microsoft.com header.s=default header.b=UEdAvs9P; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linux.microsoft.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238994AbhJMTJX (ORCPT + 99 others); Wed, 13 Oct 2021 15:09:23 -0400 Received: from linux.microsoft.com ([13.77.154.182]:49094 "EHLO linux.microsoft.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237738AbhJMTIp (ORCPT ); Wed, 13 Oct 2021 15:08:45 -0400 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 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1634152000; bh=mStA1CiElH9sJhNsB0BIIO5Ubb1vgZLKd117rmoKAGc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=UEdAvs9PmGHXUawOS05q6OkDy4PM9snsXmmjkO86TrA3uoBH2QN/rVGfuZolnyI7+ PQ8+6sNMP/4a2Rv2DaCZdh5bxW1888WsnrGbuVHwIU8CM2W/eReqRUpUnm4Fg5Oi+O rApewjghAAWVPeq+uTF2kxYWg0Cx3foBKePCukvI= 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 Cc: jannh@google.com, dm-devel@redhat.com, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-block@vger.kernel.org, linux-fscrypt@vger.kernel.org, linux-audit@redhat.com, linux-security-module@vger.kernel.org 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> X-Mailer: git-send-email 1.8.3.1 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> Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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