mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Casey Schaufler <casey@schaufler-ca.com>
To: "Dr. Greg" <greg@enjellic.com>,
	linux-security-module@vger.kernel.org,
	linux-kernel@vger.kernel.org, corbet@lwn.net,
	Casey Schaufler <casey@schaufler-ca.com>
Subject: Re: [PATCH 05/13] Add primary TSEM implementation file.
Date: Mon, 7 Aug 2023 14:00:12 -0700	[thread overview]
Message-ID: <d7ea58ea-32a8-26b9-79f2-dd0656e1aa1e@schaufler-ca.com> (raw)
In-Reply-To: <20230710102319.19716-6-greg@enjellic.com>

On 7/10/2023 3:23 AM, Dr. Greg wrote:
> The tsem.c file is the 'master' file in the TSEM implementation.
> It is responsible for initializing the LSM and providing
> implementions of the security event hooks implemented by TSEM.
>
> In addition to initializing the LSM, the set_ready() function
> implements a secondary initialization that is used to to indicate
> that security event modeling can begin.  This is required
> secondary to the fact that the cryptographic API's do not become
> ready until after the 'fs' phase of system initialization is
> complete.
>
> This file also handles the implementation of kernel command-line
> parameters that are used to configure the root security modeling
> namespace.
>
> The 'tsem_mode' parameter, if set to a value of 1, causes modeling
> to be not conducted for the root security modeling namespace.
> One use case is to allow development platform to develop security
> models without the overhead of full platform modeling.
>
> The 'tsem_digest' parameter is used to set the cryptographic hash
> function that is used to generate security state coefficients in
> the root model.  TSEM can use any cryptographic hash function
> implemented in the kernel, on a namespace by namespace basis.
> Subordinate modeling namespaces can select their hash function
> as part of the namespace creation process but the 'tsem_digest'
> parameter has to be used to set the function for the root
> modeling namespace.
>
> The hash function used in the root modeling namespace but be
> compiled into the kernel since the function is used before module
> loading becomes available.  The TSEM kernel configuration selects
> the SHA256 function to be included as the default cryptographic
> modeling function.
>
> The 'tsem_cache' variable sets the size of the pre-allocated
> structures that are used for security event modeling in the root
> modeling namespace.  This cache is used to support the modeling
> and export of events that run in atomic context.  The cache size
> can be set independently for each subordinate security modeling
> on a namespace by namespace basis.
>
> This file also contains the implementation of the tsem_names
> array that contains the ASCII text names that are assigned to
> each security event handler.  This name is used as one of the
> characteristics in the security state points that are generated.
> This array is also used to provide symbolic names for the export
> of security event descriptions, either through the TSEM control
> plane or for export to external trust orchestrators.
>
> Signed-off-by: Greg Wettstein <greg@enjellic.com>
> ---
>  security/tsem/tsem.c | 1987 ++++++++++++++++++++++++++++++++++++++++++

Please use kernel doc comments throughout.
I've made a few minor comments below, but you need to break this up
somehow for review. Also, having the data definitions elsewhere makes
review tough.

>  1 file changed, 1987 insertions(+)
>  create mode 100644 security/tsem/tsem.c
>
> diff --git a/security/tsem/tsem.c b/security/tsem/tsem.c
> new file mode 100644
> index 000000000000..8ec630354240
> --- /dev/null
> +++ b/security/tsem/tsem.c
> @@ -0,0 +1,1987 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +
> +/*
> + * Copyright (C) 2023 Enjellic Systems Development, LLC
> + * Author: Dr. Greg Wettstein <greg@enjellic.com>
> + *
> + * TSEM initialization infrastructure.
> + */
> +#define TRAPPED_MSG_LENGTH 128
> +
> +#define LOCKED true
> +#define NOLOCK false
> +
> +#include <linux/magic.h>
> +#include <linux/mman.h>
> +#include <linux/binfmts.h>
> +#include <linux/bpf.h>
> +#include <linux/ipv6.h>
> +
> +#include "tsem.h"
> +
> +struct lsm_blob_sizes tsem_blob_sizes __ro_after_init = {
> +	.lbs_task = sizeof(struct tsem_task),

Do you really want this for the task? It would seem you might
want to use the cred blob instead.

> +	.lbs_inode = sizeof(struct tsem_inode)
> +};
> +
> +enum tsem_action_type tsem_root_actions[TSEM_EVENT_CNT] = {
> +	TSEM_ACTION_EPERM	/* Undefined. */
> +};
> +
> +static struct tsem_model root_model = {
> +	.point_lock = __SPIN_LOCK_INITIALIZER(root_model.point_lock),
> +	.point_list = LIST_HEAD_INIT(root_model.point_list),
> +	.point_end_mutex = __MUTEX_INITIALIZER(root_model.point_end_mutex),
> +
> +	.trajectory_lock = __SPIN_LOCK_INITIALIZER(root_model.trajectory_lock),
> +	.trajectory_list = LIST_HEAD_INIT(root_model.trajectory_list),
> +	.trajectory_end_mutex = __MUTEX_INITIALIZER(root_model.trajectory_end_mutex),
> +
> +	.forensics_lock = __SPIN_LOCK_INITIALIZER(root_model.forensics_lock),
> +	.forensics_list = LIST_HEAD_INIT(root_model.forensics_list),
> +	.forensics_end_mutex = __MUTEX_INITIALIZER(root_model.forensics_end_mutex),
> +
> +	.pseudonym_mutex = __MUTEX_INITIALIZER(root_model.pseudonym_mutex),
> +	.pseudonym_list = LIST_HEAD_INIT(root_model.pseudonym_list)
> +};
> +
> +static struct tsem_context root_context;
> +
> +static int tsem_ready __ro_after_init;
> +
> +static bool tsem_available __ro_after_init;
> +
> +static unsigned int magazine_size __ro_after_init = TSEM_ROOT_MAGAZINE_SIZE;
> +
> +static bool no_root_modeling __ro_after_init;
> +
> +static char *default_hash_function __ro_after_init;
> +
> +static int __init set_magazine_size(char *magazine_value)
> +{
> +	if (kstrtouint(magazine_value, 0, &magazine_size))
> +		pr_warn("tsem: Failed to parse root cache size.\n");
> +
> +	if (!magazine_size) {
> +		pr_warn("tsem: Forcing non-zero cache size.\n");
> +		magazine_size = TSEM_ROOT_MAGAZINE_SIZE;
> +	}
> +
> +	pr_info("tsem: Setting default root cache size to %u.\n",
> +		magazine_size);
> +	return 1;
> +}
> +__setup("tsem_cache=", set_magazine_size);
> +
> +static int __init set_modeling_mode(char *mode_value)
> +{
> +	unsigned long mode = 0;
> +
> +	if (kstrtoul(mode_value, 0, &mode)) {
> +		pr_warn("tsem: Failed to parse modeling mode.\n");
> +		return 1;
> +	}
> +
> +	if (mode == 1)
> +		no_root_modeling = true;
> +	else
> +		pr_warn("tsem: Unknown mode specified.\n");
> +	return 1;
> +}
> +__setup("tsem_mode=", set_modeling_mode);
> +
> +static int __init set_default_hash_function(char *hash_function)
> +{
> +
> +	default_hash_function = hash_function;
> +	return 1;
> +}
> +__setup("tsem_digest=", set_default_hash_function);
> +
> +const char * const tsem_names[TSEM_EVENT_CNT] = {
> +	"undefined",
> +	"bprm_set_creds",
> +	"generic_event",
> +	"task_kill",
> +	"task_setpgid",
> +	"task_getpgid",
> +	"task_getsid",
> +	"task_setnice",
> +	"task_setioprio",
> +	"task_getioprio",
> +	"task_prlimit",
> +	"task_setrlimit",
> +	"task_setscheduler",
> +	"task_getscheduler",
> +	"task_prctl",
> +	"file_open",
> +	"mmap_file",
> +	"file_ioctl",
> +	"file_lock",
> +	"file_fcntl",
> +	"file_receive",
> +	"unix_stream_connect",
> +	"unix_may_send",
> +	"socket_create",
> +	"socket_connect",
> +	"socket_bind",
> +	"socket_accept",
> +	"socket_listen",
> +	"socket_socketpair",
> +	"socket_sendmsg",
> +	"socket_recvmsg",
> +	"socket_getsockname",
> +	"socket_getpeername",
> +	"socket_setsockopt",
> +	"socket_shutdown",
> +	"ptrace_traceme",
> +	"kernel_module_request",
> +	"kernel_load_data",
> +	"kernel_read_file",
> +	"sb_mount",
> +	"sb_umount",
> +	"sb_remount",
> +	"sb_pivotroot",
> +	"sb_statfs",
> +	"move_mount",
> +	"shm_associate",
> +	"shm_shmctl",
> +	"shm_shmat",
> +	"sem_associate",
> +	"sem_semctl",
> +	"sem_semop",
> +	"syslog",
> +	"settime",
> +	"quotactl",
> +	"quota_on",
> +	"msg_queue_associate",
> +	"msg_queue_msgctl",
> +	"msg_queue_msgsnd",
> +	"msg_queue_msgrcv",
> +	"ipc_permission",
> +	"key_alloc",
> +	"key_permission",
> +	"netlink_send",
> +	"inode_create",
> +	"inode_link",
> +	"inode_unlink",
> +	"inode_symlink",
> +	"inode_mkdir",
> +	"inode_rmdir",
> +	"inode_mknod",
> +	"inode_rename",
> +	"inode_setattr",
> +	"inode_getattr",
> +	"inode_setxattr",
> +	"inode_getxattr",
> +	"inode_listxattr",
> +	"inode_removexattr",
> +	"inode_killpriv",
> +	"tun_dev_create",
> +	"tun_dev_attach_queue",
> +	"tun_dev_attach",
> +	"tun_dev_open",
> +	"bpf",
> +	"bpf_map",
> +	"bpf_prog"
> +};
> +
> +static const int pseudo_filesystems[] = {
> +	PROC_SUPER_MAGIC,
> +	SYSFS_MAGIC,
> +	DEBUGFS_MAGIC,
> +	TMPFS_MAGIC,
> +	DEVPTS_SUPER_MAGIC,
> +	BINFMTFS_MAGIC,
> +	SECURITYFS_MAGIC,
> +	SELINUX_MAGIC,
> +	SMACK_MAGIC,
> +	CGROUP_SUPER_MAGIC,
> +	CGROUP2_SUPER_MAGIC,
> +	NSFS_MAGIC,
> +	EFIVARFS_MAGIC
> +};
> +
> +static bool bypass_inode(struct inode *inode)
> +{
> +	bool retn = true;
> +
> +	unsigned int lp;
> +
> +	if (!S_ISREG(inode->i_mode))
> +		goto done;
> +
> +	for (lp = 0; lp < ARRAY_SIZE(pseudo_filesystems); ++lp)
> +		if (inode->i_sb->s_magic == pseudo_filesystems[lp])
> +			goto done;
> +	retn = false;
> +
> + done:
> +	return retn;
> +}
> +
> +static int event_action(struct tsem_context *ctx, enum tsem_event_type event)
> +{
> +	int retn = 0;
> +
> +	if (tsem_task_trusted(current))
> +		return retn;
> +
> +	if (ctx->actions[event] == TSEM_ACTION_EPERM)
> +		retn = -EPERM;
> +
> +	return retn;
> +}
> +
> +static int return_trapped_task(enum tsem_event_type event, char *msg,

Why isn't this simply "trapped_task()"?

> +			       bool locked)
> +{
> +	int retn;
> +	struct tsem_context *ctx = tsem_context(current);
> +
> +	pr_warn("Untrusted %s: comm=%s, pid=%d, parameters='%s'\n",
> +		tsem_names[event], current->comm, task_pid_nr(current), msg);
> +
> +	if (ctx->external) {
> +		retn = tsem_export_action(event, locked);
> +		if (retn)
> +			return retn;
> +	}
> +
> +	return event_action(ctx, event);
> +}
> +
> +static int return_trapped_inode(enum tsem_event_type event,

Again, really odd function name.

... and that's all I have time for.


  reply	other threads:[~2023-08-07 21:00 UTC|newest]

Thread overview: 36+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-07-10 10:23 [PATCH 00/13] Implement Trusted Security Event Modeling Dr. Greg
2023-07-10 10:23 ` [PATCH 01/13] Update MAINTAINERS file Dr. Greg
2023-07-10 20:00   ` Randy Dunlap
2023-07-15 22:45     ` Dr. Greg
2023-07-10 10:23 ` [PATCH 02/13] Add TSEM specific documentation Dr. Greg
2023-07-11  4:37   ` Randy Dunlap
2023-07-17  0:36     ` Dr. Greg
2023-07-17  1:56       ` Randy Dunlap
2023-08-08 18:48   ` Serge Hallyn
2023-08-11 20:22     ` Dr. Greg
2024-01-04 15:54       ` Paul Moore
2024-01-05  3:54         ` Dr. Greg
2024-01-04  4:00   ` [PATCH 2/13] " Paul Moore
2024-01-05  2:55     ` Dr. Greg
2024-01-08 11:43     ` Dr. Greg
2024-02-05 16:09       ` Paul Moore
2024-02-19 11:16         ` Dr. Greg
2023-07-10 10:23 ` [PATCH 03/13] Implement CAP_TRUST capability Dr. Greg
2023-08-07 20:21   ` Casey Schaufler
2023-08-15 10:19     ` Dr. Greg
2023-08-15 17:15       ` Casey Schaufler
2023-07-10 10:23 ` [PATCH 04/13] Add TSEM master header file Dr. Greg
2023-08-07 20:39   ` Casey Schaufler
2023-08-10  2:57     ` Dr. Greg
2023-08-10 15:03       ` Casey Schaufler
2023-07-10 10:23 ` [PATCH 05/13] Add primary TSEM implementation file Dr. Greg
2023-08-07 21:00   ` Casey Schaufler [this message]
2023-08-11  7:21     ` Dr. Greg
2023-07-10 10:23 ` [PATCH 06/13] Add root domain trust implementation Dr. Greg
2023-07-10 10:23 ` [PATCH 07/13] Implement TSEM control plane Dr. Greg
2023-07-10 10:23 ` [PATCH 08/13] Add namespace implementation Dr. Greg
2023-07-10 10:23 ` [PATCH 09/13] Add security event description export facility Dr. Greg
2023-07-10 10:23 ` [PATCH 10/13] Add event description implementation Dr. Greg
2023-07-10 10:23 ` [PATCH 11/13] Implement security event mapping Dr. Greg
2023-07-10 10:23 ` [PATCH 12/13] Implement an internal Trusted Modeling Agent Dr. Greg
2023-07-10 10:23 ` [PATCH 13/13] Activate the configuration and build of the TSEM LSM Dr. Greg

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=d7ea58ea-32a8-26b9-79f2-dd0656e1aa1e@schaufler-ca.com \
    --to=casey@schaufler-ca.com \
    --cc=corbet@lwn.net \
    --cc=greg@enjellic.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-security-module@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®