| /* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ | |
| /* | |
| * Container Security Monitor module | |
| * | |
| * Copyright (c) 2018 Google, Inc | |
| */ | |
| #define pr_fmt(fmt) "container-security-monitor: " fmt | |
| #include <linux/kernel.h> | |
| #include <linux/security.h> | |
| #include <linux/fs.h> | |
| #include <linux/rwsem.h> | |
| #include <linux/binfmts.h> | |
| #include <linux/xattr.h> | |
| #include <config.pb.h> | |
| #include <event.pb.h> | |
| #include <pb_encode.h> | |
| #include <pb_decode.h> | |
| #include "monitoring_protocol.h" | |
| /* Part of the CSM configuration response. */ | |
| #define CSM_VERSION 1 | |
| /* protects csm_*_enabled and configurations. */ | |
| extern struct rw_semaphore csm_rwsem_config; | |
| /* | |
| * Is monitoring enabled? Defaults to disabled. | |
| * These variables might be used as gates without locking (as processor ensures | |
| * valid proper access for native scalar values) so it can bail quickly. | |
| */ | |
| extern bool csm_enabled; | |
| extern bool csm_execute_enabled; | |
| extern bool csm_memexec_enabled; | |
| /* Configuration options for execute collector. */ | |
| struct execute_config { | |
| size_t argv_limit; | |
| size_t envp_limit; | |
| char *envp_allowlist; | |
| }; | |
| extern struct execute_config csm_execute_config; | |
| /* pipe to forward events to user-mode. */ | |
| extern struct rw_semaphore csm_rwsem_pipe; | |
| extern struct file *csm_user_write_pipe; | |
| /* Stats on LSM events. */ | |
| struct container_stats { | |
| size_t proto_encoding_failed; | |
| size_t event_writing_failed; | |
| size_t workqueue_failed; | |
| size_t size_picking_failed; | |
| size_t pipe_already_opened; | |
| size_t csm_setxattr; | |
| }; | |
| extern struct container_stats csm_stats; | |
| /* Streams file numbers are unknown from the kernel */ | |
| #define STDIN_FILENO 0 | |
| #define STDOUT_FILENO 1 | |
| #define STDERR_FILENO 2 | |
| /* security attribute for file provenance. */ | |
| #define XATTR_SECURITY_CSM XATTR_SECURITY_PREFIX "csm" | |
| /* monitor functions */ | |
| int csm_update_config_from_buffer(void *data, size_t size); | |
| /* send event to userland */ | |
| int csm_sendeventproto(const pb_msgdesc_t *fields, schema_Event *event); | |
| /* process events functions */ | |
| int csm_bprm_check_security(struct linux_binprm *bprm); | |
| void csm_task_exit(struct task_struct *task); | |
| void csm_task_post_alloc(struct task_struct *task); | |
| int get_process_uuid_by_pid(pid_t pid_nr, char *buffer, size_t size); | |
| /* memory execution events functions */ | |
| int csm_mprotect(struct vm_area_struct *vma, unsigned long reqprot, | |
| unsigned long prot); | |
| int csm_mmap_file(struct file *file, unsigned long reqprot, | |
| unsigned long prot, unsigned long flags); | |
| /* Tracking of file modification provenance. */ | |
| void csm_file_pre_free(struct file *file); | |
| /* nano functions */ | |
| bool pb_encode_string_field(pb_ostream_t *stream, const pb_field_t *field, | |
| void * const *arg); | |
| bool pb_decode_string_field(pb_istream_t *stream, const pb_field_t *field, | |
| void **arg); | |
| ssize_t pb_encode_string_field_limit(pb_ostream_t *stream, | |
| const pb_field_t *field, | |
| void * const *arg, size_t limit); | |
| bool pb_encode_string_array(pb_ostream_t *stream, const pb_field_t *field, | |
| void * const *arg); | |
| bool pb_decode_string_array(pb_istream_t *stream, const pb_field_t *field, | |
| void **arg); | |
| bool pb_encode_uuid_field(pb_ostream_t *stream, const pb_field_t *field, | |
| void * const *arg); | |
| bool pb_encode_ip4(pb_ostream_t *stream, const pb_field_t *field, | |
| void * const *arg); | |
| bool pb_encode_ip6(pb_ostream_t *stream, const pb_field_t *field, | |
| void * const *arg); | |