[PATCH 04/10] CaitSith: Add header file.

Tetsuo Handa penguin-kernel at I-love.SAKURA.ne.jp
Wed Nov 2 17:10:19 UTC 2022


The main point of this submission is to demonstrate how an LSM module
which can be loaded using /sbin/insmod can work, and to provide
consideration points for making changes for LSM stacking in a way that
will not lock out LSM modules which can be loaded using /sbin/insmod .

CaitSith was developed as next version of TOMOYO. But since it became
too different to call as TOMOYO (this was a fundamental change as if
SELinux stops using filesystem's extended attributes), I gave this module
a new name. Background of developing this module is explained in
https://I-love.SAKURA.ne.jp/tomoyo/CaitSith-en.pdf .

This file defines constants, structures, and inline functions used by
CaitSith. Please ignore redundancy, for this submission is just an output
 from repository which supports 2.6.27+ kernels with LINUX_VERSION_CODE
removed.

Signed-off-by: Tetsuo Handa <penguin-kernel at I-love.SAKURA.ne.jp>
---
 security/caitsith/caitsith.h | 919 +++++++++++++++++++++++++++++++++++
 1 file changed, 919 insertions(+)
 create mode 100644 security/caitsith/caitsith.h

diff --git a/security/caitsith/caitsith.h b/security/caitsith/caitsith.h
new file mode 100644
index 000000000000..b85050d2d5e3
--- /dev/null
+++ b/security/caitsith/caitsith.h
@@ -0,0 +1,919 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * caitsith.h
+ *
+ * Copyright (C) 2005-2012  NTT DATA CORPORATION
+ *
+ * Version: 0.2.10   2021/06/06
+ */
+
+#ifndef _SECURITY_CAITSITH_INTERNAL_H
+#define _SECURITY_CAITSITH_INTERNAL_H
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/utime.h>
+#include <linux/file.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/highmem.h>
+#include <linux/poll.h>
+#include <linux/binfmts.h>
+#include <linux/delay.h>
+#include <linux/sched.h>
+#include <linux/dcache.h>
+#include <linux/mount.h>
+#include <linux/net.h>
+#include <linux/inet.h>
+#include <linux/in.h>
+#include <linux/in6.h>
+#include <linux/un.h>
+#include <linux/namei.h>
+#include <linux/fs_struct.h>
+#include <linux/hash.h>
+#include <linux/kthread.h>
+#include <linux/magic.h>
+#include <linux/uaccess.h>
+#include <linux/sched/signal.h>
+#include <net/sock.h>
+#include <net/af_unix.h>
+#include <net/ip.h>
+#include <net/ipv6.h>
+#include <net/udp.h>
+#include <linux/ctype.h>
+#include <linux/magic.h>
+#include <uapi/linux/mount.h>
+#include <linux/uidgid.h>
+
+/* Index numbers for Capability Controls. */
+enum cs_capability_acl_index {
+	/* socket(PF_ROUTE, *, *)                                      */
+	CS_USE_ROUTE_SOCKET,
+	/* socket(PF_PACKET, *, *)                                     */
+	CS_USE_PACKET_SOCKET,
+	CS_MAX_CAPABILITY_INDEX
+};
+
+/* Enumeration definition for internal use. */
+
+/* Index numbers for "struct cs_condition". */
+enum cs_conditions_index {
+	CS_INVALID_CONDITION,
+	CS_SELF_UID,             /* current_uid()   */
+	CS_SELF_EUID,            /* current_euid()  */
+	CS_SELF_SUID,            /* current_suid()  */
+	CS_SELF_FSUID,           /* current_fsuid() */
+	CS_SELF_GID,             /* current_gid()   */
+	CS_SELF_EGID,            /* current_egid()  */
+	CS_SELF_SGID,            /* current_sgid()  */
+	CS_SELF_FSGID,           /* current_fsgid() */
+	CS_SELF_PID,             /* sys_getpid()   */
+	CS_SELF_PPID,            /* sys_getppid()  */
+	CS_SELF_DOMAIN,
+	CS_SELF_EXE,
+	CS_EXEC_ARGC,            /* "struct linux_binprm *"->argc */
+	CS_EXEC_ENVC,            /* "struct linux_binprm *"->envc */
+	CS_OBJ_IS_SOCKET,        /* S_IFSOCK */
+	CS_OBJ_IS_SYMLINK,       /* S_IFLNK */
+	CS_OBJ_IS_FILE,          /* S_IFREG */
+	CS_OBJ_IS_BLOCK_DEV,     /* S_IFBLK */
+	CS_OBJ_IS_DIRECTORY,     /* S_IFDIR */
+	CS_OBJ_IS_CHAR_DEV,      /* S_IFCHR */
+	CS_OBJ_IS_FIFO,          /* S_IFIFO */
+	CS_MODE_SETUID,          /* S_ISUID */
+	CS_MODE_SETGID,          /* S_ISGID */
+	CS_MODE_STICKY,          /* S_ISVTX */
+	CS_MODE_OWNER_READ,      /* S_IRUSR */
+	CS_MODE_OWNER_WRITE,     /* S_IWUSR */
+	CS_MODE_OWNER_EXECUTE,   /* S_IXUSR */
+	CS_MODE_GROUP_READ,      /* S_IRGRP */
+	CS_MODE_GROUP_WRITE,     /* S_IWGRP */
+	CS_MODE_GROUP_EXECUTE,   /* S_IXGRP */
+	CS_MODE_OTHERS_READ,     /* S_IROTH */
+	CS_MODE_OTHERS_WRITE,    /* S_IWOTH */
+	CS_MODE_OTHERS_EXECUTE,  /* S_IXOTH */
+	CS_TRANSIT_DOMAIN,
+	CS_COND_SARG0,
+	CS_COND_SARG1,
+	CS_COND_SARG2,
+	CS_COND_SARG3,
+	CS_COND_NARG0,
+	CS_COND_NARG1,
+	CS_COND_NARG2,
+	CS_COND_IPARG,
+	CS_COND_DOMAIN,
+	CS_IMM_GROUP,
+	CS_IMM_NAME_ENTRY,
+	CS_IMM_NUMBER_ENTRY1,
+	CS_IMM_NUMBER_ENTRY2,
+#ifdef CONFIG_SECURITY_CAITSITH_NETWORK
+	CS_IMM_IPV4ADDR_ENTRY1,
+	CS_IMM_IPV4ADDR_ENTRY2,
+	CS_IMM_IPV6ADDR_ENTRY1,
+	CS_IMM_IPV6ADDR_ENTRY2,
+#endif
+	CS_ARGV_ENTRY,
+	CS_ENVP_ENTRY,
+	CS_PATH_ATTRIBUTE_START = 192,
+	CS_PATH_ATTRIBUTE_END = 255
+} __packed;
+
+enum cs_path_attribute_index {
+	CS_PATH_ATTRIBUTE_UID,
+	CS_PATH_ATTRIBUTE_GID,
+	CS_PATH_ATTRIBUTE_INO,
+	CS_PATH_ATTRIBUTE_TYPE,
+	CS_PATH_ATTRIBUTE_MAJOR,
+	CS_PATH_ATTRIBUTE_MINOR,
+	CS_PATH_ATTRIBUTE_PERM,
+	CS_PATH_ATTRIBUTE_DEV_MAJOR,
+	CS_PATH_ATTRIBUTE_DEV_MINOR,
+	CS_PATH_ATTRIBUTE_FSMAGIC,
+	CS_MAX_PATH_ATTRIBUTE
+} __packed;
+
+/* Index numbers for group entries. */
+enum cs_group_id {
+	CS_STRING_GROUP,
+	CS_NUMBER_GROUP,
+#ifdef CONFIG_SECURITY_CAITSITH_NETWORK
+	CS_IP_GROUP,
+#endif
+	CS_MAX_GROUP
+} __packed;
+
+/* Index numbers for functionality. */
+enum cs_mac_index {
+	CS_MAC_EXECUTE,
+	CS_MAC_READ,
+	CS_MAC_WRITE,
+	CS_MAC_APPEND,
+	CS_MAC_CREATE,
+	CS_MAC_UNLINK,
+#ifdef CONFIG_SECURITY_CAITSITH_GETATTR
+	CS_MAC_GETATTR,
+#endif
+	CS_MAC_MKDIR,
+	CS_MAC_RMDIR,
+	CS_MAC_MKFIFO,
+	CS_MAC_MKSOCK,
+	CS_MAC_TRUNCATE,
+	CS_MAC_SYMLINK,
+	CS_MAC_MKBLOCK,
+	CS_MAC_MKCHAR,
+	CS_MAC_LINK,
+	CS_MAC_RENAME,
+	CS_MAC_CHMOD,
+	CS_MAC_CHOWN,
+	CS_MAC_CHGRP,
+	CS_MAC_IOCTL,
+	CS_MAC_CHROOT,
+	CS_MAC_MOUNT,
+	CS_MAC_UMOUNT,
+	CS_MAC_PIVOT_ROOT,
+#ifdef CONFIG_SECURITY_CAITSITH_NETWORK
+	CS_MAC_INET_STREAM_BIND,
+	CS_MAC_INET_STREAM_LISTEN,
+	CS_MAC_INET_STREAM_CONNECT,
+	CS_MAC_INET_STREAM_ACCEPT,
+	CS_MAC_INET_DGRAM_BIND,
+	CS_MAC_INET_DGRAM_SEND,
+	CS_MAC_INET_RAW_BIND,
+	CS_MAC_INET_RAW_SEND,
+	CS_MAC_UNIX_STREAM_BIND,
+	CS_MAC_UNIX_STREAM_LISTEN,
+	CS_MAC_UNIX_STREAM_CONNECT,
+	CS_MAC_UNIX_STREAM_ACCEPT,
+	CS_MAC_UNIX_DGRAM_BIND,
+	CS_MAC_UNIX_DGRAM_SEND,
+	CS_MAC_UNIX_SEQPACKET_BIND,
+	CS_MAC_UNIX_SEQPACKET_LISTEN,
+	CS_MAC_UNIX_SEQPACKET_CONNECT,
+	CS_MAC_UNIX_SEQPACKET_ACCEPT,
+#endif
+#ifdef CONFIG_SECURITY_CAITSITH_ENVIRON
+	CS_MAC_ENVIRON,
+#endif
+	CS_MAC_MODIFY_POLICY,
+#ifdef CONFIG_SECURITY_CAITSITH_CAPABILITY
+	CS_MAC_USE_NETLINK_SOCKET,
+	CS_MAC_USE_PACKET_SOCKET,
+#endif
+#ifdef CONFIG_SECURITY_CAITSITH_AUTO_DOMAIN_TRANSITION
+	CS_MAC_AUTO_DOMAIN_TRANSITION,
+#endif
+#ifdef CONFIG_SECURITY_CAITSITH_MANUAL_DOMAIN_TRANSITION
+	CS_MAC_MANUAL_DOMAIN_TRANSITION,
+#endif
+	CS_MAX_MAC_INDEX,
+	/* Map undefined functions to CS_MAX_MAC_INDEX */
+#ifndef CONFIG_SECURITY_CAITSITH_GETATTR
+	CS_MAC_GETATTR = CS_MAX_MAC_INDEX,
+#endif
+#ifndef CONFIG_SECURITY_CAITSITH_NETWORK
+	CS_MAC_INET_STREAM_BIND = CS_MAX_MAC_INDEX,
+	CS_MAC_INET_STREAM_LISTEN = CS_MAX_MAC_INDEX,
+	CS_MAC_INET_STREAM_CONNECT = CS_MAX_MAC_INDEX,
+	CS_MAC_INET_STREAM_ACCEPT = CS_MAX_MAC_INDEX,
+	CS_MAC_INET_DGRAM_BIND = CS_MAX_MAC_INDEX,
+	CS_MAC_INET_DGRAM_SEND = CS_MAX_MAC_INDEX,
+	CS_MAC_INET_RAW_BIND = CS_MAX_MAC_INDEX,
+	CS_MAC_INET_RAW_SEND = CS_MAX_MAC_INDEX,
+	CS_MAC_UNIX_STREAM_BIND = CS_MAX_MAC_INDEX,
+	CS_MAC_UNIX_STREAM_LISTEN = CS_MAX_MAC_INDEX,
+	CS_MAC_UNIX_STREAM_CONNECT = CS_MAX_MAC_INDEX,
+	CS_MAC_UNIX_STREAM_ACCEPT = CS_MAX_MAC_INDEX,
+	CS_MAC_UNIX_DGRAM_BIND = CS_MAX_MAC_INDEX,
+	CS_MAC_UNIX_DGRAM_SEND = CS_MAX_MAC_INDEX,
+	CS_MAC_UNIX_SEQPACKET_BIND = CS_MAX_MAC_INDEX,
+	CS_MAC_UNIX_SEQPACKET_LISTEN = CS_MAX_MAC_INDEX,
+	CS_MAC_UNIX_SEQPACKET_CONNECT = CS_MAX_MAC_INDEX,
+	CS_MAC_UNIX_SEQPACKET_ACCEPT = CS_MAX_MAC_INDEX,
+#endif
+#ifndef CONFIG_SECURITY_CAITSITH_ENVIRON
+	CS_MAC_ENVIRON = CS_MAX_MAC_INDEX,
+#endif
+#ifndef CONFIG_SECURITY_CAITSITH_CAPABILITY
+	CS_MAC_USE_NETLINK_SOCKET = CS_MAX_MAC_INDEX,
+	CS_MAC_USE_PACKET_SOCKET = CS_MAX_MAC_INDEX,
+#endif
+#ifndef CONFIG_SECURITY_CAITSITH_AUTO_DOMAIN_TRANSITION
+	CS_MAC_AUTO_DOMAIN_TRANSITION = CS_MAX_MAC_INDEX,
+#endif
+#ifndef CONFIG_SECURITY_CAITSITH_MANUAL_DOMAIN_TRANSITION
+	CS_MAC_MANUAL_DOMAIN_TRANSITION = CS_MAX_MAC_INDEX,
+#endif
+} __packed;
+
+/* Index numbers for statistic information. */
+enum cs_memory_stat_type {
+	CS_MEMORY_POLICY,
+	CS_MEMORY_AUDIT,
+	CS_MEMORY_QUERY,
+	CS_MAX_MEMORY_STAT
+} __packed;
+
+enum cs_matching_result {
+	CS_MATCHING_UNMATCHED,
+	CS_MATCHING_ALLOWED,
+	CS_MATCHING_DENIED,
+	CS_MAX_MATCHING
+} __packed;
+
+/* Index numbers for stat(). */
+enum cs_path_stat_index {
+	/* Do not change this order. */
+	CS_PATH1,
+	CS_PATH1_PARENT,
+	CS_PATH2,
+	CS_PATH2_PARENT,
+	CS_MAX_PATH_STAT
+} __packed;
+
+/* Index numbers for entry type. */
+enum cs_policy_id {
+	CS_ID_GROUP,
+#ifdef CONFIG_SECURITY_CAITSITH_NETWORK
+	CS_ID_IP_GROUP,
+#endif
+	CS_ID_STRING_GROUP,
+	CS_ID_NUMBER_GROUP,
+	CS_ID_CONDITION,
+	CS_ID_NAME,
+	CS_ID_ACL,
+	CS_ID_DOMAIN,
+	CS_MAX_POLICY
+} __packed;
+
+/* Index numbers for statistic information. */
+enum cs_policy_stat_type {
+	CS_STAT_POLICY_UPDATES,
+	CS_STAT_REQUEST_DENIED,
+	CS_MAX_POLICY_STAT
+} __packed;
+
+/* Index numbers for /sys/kernel/security/caitsith/ interfaces. */
+enum cs_securityfs_interface_index {
+	CS_POLICY,
+	CS_PROCESS_STATUS,
+	CS_AUDIT,
+	CS_VERSION,
+	CS_QUERY,
+} __packed;
+
+/* Index numbers for special mount operations. */
+enum cs_special_mount {
+	CS_MOUNT_BIND,            /* mount --bind /source /dest   */
+	CS_MOUNT_MOVE,            /* mount --move /old /new       */
+	CS_MOUNT_REMOUNT,         /* mount -o remount /dir        */
+	CS_MOUNT_MAKE_UNBINDABLE, /* mount --make-unbindable /dir */
+	CS_MOUNT_MAKE_PRIVATE,    /* mount --make-private /dir    */
+	CS_MOUNT_MAKE_SLAVE,      /* mount --make-slave /dir      */
+	CS_MOUNT_MAKE_SHARED,     /* mount --make-shared /dir     */
+	CS_MAX_SPECIAL_MOUNT
+} __packed;
+
+/* Index numbers for type of numeric values. */
+enum cs_value_type {
+	CS_VALUE_TYPE_INVALID,
+	CS_VALUE_TYPE_DECIMAL,
+	CS_VALUE_TYPE_OCTAL,
+	CS_VALUE_TYPE_HEXADECIMAL,
+} __packed;
+
+/* Constants definition for internal use. */
+
+/*
+ * CaitSith uses this hash only when appending a string into the string table.
+ * Frequency of appending strings is very low. So we don't need large (e.g.
+ * 64k) hash size. 256 will be sufficient.
+ */
+#define CS_HASH_BITS 8
+#define CS_MAX_HASH (1u << CS_HASH_BITS)
+
+/*
+ * CaitSith checks only SOCK_STREAM, SOCK_DGRAM, SOCK_RAW, SOCK_SEQPACKET.
+ * Therefore, we don't need SOCK_MAX.
+ */
+#define CS_SOCK_MAX 6
+
+/* Size of temporary buffer for execve() operation. */
+#define CS_EXEC_TMPSIZE     4096
+
+/* Patterns for auditing logs quota. */
+#define CS_MAX_LOG_QUOTA 256
+
+/* Garbage collector is trying to kfree() this element. */
+#define CS_GC_IN_PROGRESS -1
+
+/* Current thread is doing open(3) ? */
+#define CS_OPEN_FOR_IOCTL_ONLY           2
+/* Current thread is doing do_execve() ? */
+#define CS_TASK_IS_IN_EXECVE             4
+/*
+ * Current thread is allowed to modify policy via
+ * /sys/kernel/security/caitsith/ interface?
+ */
+#define CS_TASK_IS_MANAGER               8
+
+/*
+ * Retry this request. Returned by cs_supervisor() if policy violation has
+ * occurred in enforcing mode and the userspace daemon decided to retry.
+ *
+ * We must choose a positive value in order to distinguish "granted" (which is
+ * 0) and "rejected" (which is a negative value) and "retry".
+ */
+#define CS_RETRY_REQUEST 1
+
+/* Size of read buffer for /sys/kernel/security/caitsith/ interface. */
+#define CS_MAX_IO_READ_QUEUE 64
+
+/* Structure definition for internal use. */
+
+/* Common header for holding ACL entries. */
+struct cs_acl_head {
+	struct list_head list;
+	s8 is_deleted; /* true or false or CS_GC_IN_PROGRESS */
+} __packed;
+
+/* Common header for shared entries. */
+struct cs_shared_acl_head {
+	struct list_head list;
+	atomic_t users;
+} __packed;
+
+/* Common header for individual entries. */
+struct cs_acl_info {
+	struct list_head list;
+	struct list_head acl_info_list;
+	struct cs_condition *cond; /* Maybe NULL. */
+	bool is_deleted;
+	bool is_deny;
+	u16 priority;
+	u8 audit;
+};
+
+/* Structure for "string_group"/"number_group"/"ip_group" directive. */
+struct cs_group {
+	struct cs_shared_acl_head head;
+	/* Name of group (without leading "@"). */
+	const struct cs_path_info *group_name;
+	/*
+	 * List of "struct cs_string_group" or "struct cs_number_group" or
+	 * "struct cs_ip_group".
+	 */
+	struct list_head member_list;
+};
+
+/* Structure for "string_group" directive. */
+struct cs_string_group {
+	struct cs_acl_head head;
+	const struct cs_path_info *member_name;
+};
+
+/* Structure for "number_group" directive. */
+struct cs_number_group {
+	struct cs_acl_head head;
+	u8 radix;
+	unsigned long value[2];
+};
+
+/* Structure for "ip_group" directive. */
+struct cs_ip_group {
+	struct cs_acl_head head;
+	bool is_ipv6;
+	/* Structure for holding an IP address. */
+	struct in6_addr ip[2]; /* Big endian. */
+};
+
+/* Subset of "struct stat". Used by conditional ACL and audit logs. */
+struct cs_mini_stat {
+	kuid_t uid;
+	kgid_t gid;
+	ino_t ino;
+	umode_t mode;
+	dev_t dev;
+	dev_t rdev;
+	unsigned long fsmagic;
+};
+
+/* Structure for dumping argv[] and envp[] of "struct linux_binprm". */
+struct cs_page_dump {
+	struct page *page;    /* Previously dumped page. */
+	char *data;           /* Contents of "page". Size is PAGE_SIZE. */
+};
+
+/* Structure for entries which follows "struct cs_condition". */
+union cs_condition_element {
+	struct {
+		enum cs_conditions_index left;
+		enum cs_conditions_index right;
+		bool is_not;
+		u8 radix;
+	};
+	struct cs_group *group;
+	const struct cs_path_info *path;
+	u32 ip; /* Repeat 4 times if IPv6 address. */
+	unsigned long value;
+};
+
+/* Structure for optional arguments. */
+struct cs_condition {
+	struct cs_shared_acl_head head;
+	u32 size; /* Memory size allocated for this entry. */
+	/* union cs_condition_element condition[]; */
+};
+
+/* Structure for holding a token. */
+struct cs_path_info {
+	const char *name;
+	u32 hash;          /* = full_name_hash(name, strlen(name)) */
+	u32 total_len;     /* = strlen(name)                       */
+	u32 const_len;     /* = cs_const_part_length(name)        */
+};
+
+/* Structure for request info. */
+struct cs_request_info {
+	/* For holding parameters. */
+	struct cs_request_param {
+		const struct cs_path_info *s[4];
+		unsigned long i[3];
+#ifdef CONFIG_SECURITY_CAITSITH_NETWORK
+		const u8 *ip; /* Big endian. */
+		bool is_ipv6;
+#endif
+	} param;
+	/* For holding pathnames and attributes. */
+	struct {
+		/*
+		 * True if cs_get_attributes() was already called, false
+		 * otherwise.
+		 */
+		bool validate_done;
+		/* True if @stat[] is valid. */
+		bool stat_valid[CS_MAX_PATH_STAT];
+		/* Pointer to file objects. */
+		struct path path[2];
+		/*
+		 * Information on @path[0], @path[0]'s parent directory,
+		 * @path[1] and @path[1]'s parent directory.
+		 */
+		struct cs_mini_stat stat[CS_MAX_PATH_STAT];
+		/*
+		 * Name of @path[0] and @path[1].
+		 * Cleared by cs_clear_request_info().
+		 */
+		struct cs_path_info pathname[2];
+	} obj;
+	struct {
+		struct linux_binprm *bprm;
+		struct cs_domain_info *previous_domain;
+		/* For dumping argv[] and envp[]. */
+		struct cs_page_dump dump;
+		/* For temporary use. Size is CS_EXEC_TMPSIZE bytes. */
+		char *tmp;
+	};
+	/*
+	 * Name of current thread's executable.
+	 * Cleared by cs_clear_request_info().
+	 */
+	struct cs_path_info exename;
+	/*
+	 * Matching "struct cs_acl_info" is copied. Used for caitsith-queryd.
+	 * Valid until cs_read_unlock().
+	 */
+	struct cs_acl_info *matched_acl;
+	/*
+	 * Matching domain transition is copied.
+	 * Valid until cs_read_unlock().
+	 */
+	const struct cs_path_info *transition;
+	const struct cs_path_info *transition_candidate;
+	/*
+	 * For holding operation index used for this request.
+	 * One of values in "enum cs_mac_index".
+	 */
+	enum cs_mac_index type;
+	/* For holding matching result. */
+	enum cs_matching_result result;
+	/*
+	 * For counting number of retries made for this request.
+	 * This counter is incremented whenever cs_supervisor() returned
+	 * CS_RETRY_REQUEST.
+	 */
+	u8 retry;
+	/* For holding max audit log count for this matching entry. */
+	u8 audit;
+	/*
+	 * Set to true if condition could not be checked due to out of memory.
+	 * This flag is used for returning out of memory flag back to
+	 * cs_check_acl_list(). Thus, this flag will not be set if out of
+	 * memory occurred before cs_check_acl_list() is called.
+	 */
+	bool failed_by_oom;
+};
+
+/* Structure for domain information. */
+struct cs_domain_info {
+	struct list_head list;
+	/* Name of this domain. Never NULL. */
+	const struct cs_path_info *domainname;
+};
+
+/* Structure for holding string data. */
+struct cs_name {
+	struct cs_shared_acl_head head;
+	int size; /* Memory size allocated for this entry. */
+	struct cs_path_info entry;
+};
+
+/*
+ * Structure for reading/writing policy via /sys/kernel/security/caitsith/
+ * interfaces.
+ */
+struct cs_io_buffer {
+	/* Exclusive lock for this structure.   */
+	struct mutex io_sem;
+	char __user *read_user_buf;
+	size_t read_user_buf_avail;
+	struct {
+		struct list_head *group;
+		struct list_head *acl;
+		struct list_head *subacl;
+		const union cs_condition_element *cond;
+		size_t avail;
+		unsigned int step;
+		unsigned int query_index;
+		u16 index;
+		u8 cond_step;
+		u8 w_pos;
+		enum cs_mac_index acl_index;
+		bool eof;
+		bool print_this_acl_only;
+		bool version_done;
+		bool stat_done;
+		bool quota_done;
+		bool group_done;
+		const char *w[CS_MAX_IO_READ_QUEUE];
+	} r;
+	struct {
+		char *data;
+		struct cs_acl_info *acl;
+		size_t avail;
+		enum cs_mac_index acl_index;
+		bool is_delete;
+		bool is_deny;
+		u16 priority;
+	} w;
+	/* Buffer for reading.                  */
+	char *read_buf;
+	/* Size of read buffer.                 */
+	size_t readbuf_size;
+	/* Buffer for writing.                  */
+	char *write_buf;
+	/* Size of write buffer.                */
+	size_t writebuf_size;
+	/* Type of interface. */
+	enum cs_securityfs_interface_index type;
+	/* Users counter protected by cs_io_buffer_list_lock. */
+	u8 users;
+	/* List for telling GC not to kfree() elements. */
+	struct list_head list;
+};
+
+/* Structure for representing YYYY/MM/DD hh/mm/ss. */
+struct cs_time {
+	u16 year;
+	u8 month;
+	u8 day;
+	u8 hour;
+	u8 min;
+	u8 sec;
+};
+
+/* Prototype definition for internal use. */
+
+int __init cs_init_module(void);
+void cs_check_profile(void);
+bool cs_dump_page(struct linux_binprm *bprm, unsigned long pos,
+		  struct cs_page_dump *dump);
+bool cs_get_exename(struct cs_path_info *buf);
+bool cs_manager(void);
+bool cs_transit_domain(const char *domainname);
+char *cs_encode(const char *str);
+char *cs_encode2(const char *str, int str_len);
+char *cs_realpath(const struct path *path);
+char *cs_get_exe(void);
+int cs_audit_log(struct cs_request_info *r);
+int cs_check_acl(struct cs_request_info *r, const bool clear);
+void cs_del_condition(struct list_head *element);
+void cs_fill_path_info(struct cs_path_info *ptr);
+void cs_get_attributes(struct cs_request_info *r);
+void cs_notify_gc(struct cs_io_buffer *head, const bool is_register);
+void cs_populate_patharg(struct cs_request_info *r, const bool first);
+void cs_transition_failed(const char *domainname);
+void cs_warn_oom(const char *function);
+int cs_chroot_permission(const struct path *path);
+int cs_chmod_permission(const struct path *path, mode_t mode);
+int cs_chown_permission(const struct path *path, kuid_t user, kgid_t group);
+int cs_fcntl_permission(struct file *file, unsigned int cmd,
+			unsigned long arg);
+int cs_ioctl_permission(struct file *filp, unsigned int cmd,
+			unsigned long arg);
+int cs_link_permission(const struct path *old, const struct path *new);
+int cs_mkdir_permission(const struct path *path, unsigned int mode);
+int cs_mknod_permission(const struct path *path, const unsigned int mode,
+			unsigned int dev);
+int cs_mount_permission(const char *dev_name, const struct path *path,
+			const char *type, unsigned long flags,
+			void *data_page);
+int cs_move_mount_permission(const struct path *from_path,
+			     const struct path *to_path);
+int cs_pivot_root_permission(const struct path *old_path,
+			     const struct path *new_path);
+int cs_rename_permission(const struct path *old, const struct path *new);
+int cs_symlink_permission(const struct path *path, const char *from);
+int cs_truncate_permission(const struct path *path);
+int cs_umount_permission(const struct path *path, int flags);
+int cs_unlink_permission(const struct path *path);
+int cs_socket_create_permission(int family, int type, int protocol);
+int cs_socket_bind_permission(struct socket *sock, struct sockaddr *addr,
+			      int addr_len);
+int cs_socket_connect_permission(struct socket *sock, struct sockaddr *addr,
+				 int addr_len);
+int cs_socket_listen_permission(struct socket *sock);
+int cs_socket_post_accept_permission(struct socket *sock,
+				     struct socket *newsock);
+int cs_socket_sendmsg_permission(struct socket *sock,
+				 struct msghdr *msg, int size);
+int cs_rmdir_permission(const struct path *path);
+int cs_getattr_permission(const struct path *path);
+bool cs_capable(const u8 operation);
+int cs_open_permission(const struct path *path, const int flag);
+
+/* Variable definition for internal use. */
+
+extern bool cs_policy_loaded;
+extern struct cs_domain_info cs_kernel_domain;
+extern struct cs_path_info cs_null_name;
+extern struct list_head cs_acl_list[CS_MAX_MAC_INDEX];
+extern struct list_head cs_condition_list;
+extern struct list_head cs_domain_list;
+extern struct list_head cs_group_list[CS_MAX_GROUP];
+extern struct list_head cs_name_list[CS_MAX_HASH];
+extern struct mutex cs_policy_lock;
+extern struct srcu_struct cs_ss;
+extern unsigned int cs_memory_used[CS_MAX_MEMORY_STAT];
+
+/* Inlined functions for internal use. */
+
+/**
+ * cs_pathcmp - strcmp() for "struct cs_path_info" structure.
+ *
+ * @a: Pointer to "struct cs_path_info".
+ * @b: Pointer to "struct cs_path_info".
+ *
+ * Returns true if @a != @b, false otherwise.
+ */
+static inline bool cs_pathcmp(const struct cs_path_info *a,
+			      const struct cs_path_info *b)
+{
+	return a->hash != b->hash || strcmp(a->name, b->name);
+}
+
+/**
+ * cs_read_lock - Take lock for protecting policy.
+ *
+ * Returns index number for cs_read_unlock().
+ */
+static inline int cs_read_lock(void)
+{
+	return srcu_read_lock(&cs_ss);
+}
+
+/**
+ * cs_read_unlock - Release lock for protecting policy.
+ *
+ * @idx: Index number returned by cs_read_lock().
+ *
+ * Returns nothing.
+ */
+static inline void cs_read_unlock(const int idx)
+{
+	srcu_read_unlock(&cs_ss, idx);
+}
+
+/**
+ * cs_sys_getppid - Copy of getppid().
+ *
+ * Returns parent process's PID.
+ *
+ * Alpha does not have getppid() defined. To be able to build this module on
+ * Alpha, I have to copy getppid() from kernel/timer.c.
+ */
+static inline pid_t cs_sys_getppid(void)
+{
+	pid_t pid;
+
+	rcu_read_lock();
+	pid = task_tgid_vnr(rcu_dereference(current->real_parent));
+	rcu_read_unlock();
+	return pid;
+}
+
+/**
+ * cs_sys_getpid - Copy of getpid().
+ *
+ * Returns current thread's PID.
+ *
+ * Alpha does not have getpid() defined. To be able to build this module on
+ * Alpha, I have to copy getpid() from kernel/timer.c.
+ */
+static inline pid_t cs_sys_getpid(void)
+{
+	return task_tgid_vnr(current);
+}
+
+/**
+ * cs_put_condition - Drop reference on "struct cs_condition".
+ *
+ * @cond: Pointer to "struct cs_condition". Maybe NULL.
+ *
+ * Returns nothing.
+ */
+static inline void cs_put_condition(struct cs_condition *cond)
+{
+	if (cond)
+		atomic_dec(&cond->head.users);
+}
+
+/**
+ * cs_put_group - Drop reference on "struct cs_group".
+ *
+ * @group: Pointer to "struct cs_group". Maybe NULL.
+ *
+ * Returns nothing.
+ */
+static inline void cs_put_group(struct cs_group *group)
+{
+	if (group)
+		atomic_dec(&group->head.users);
+}
+
+/**
+ * cs_put_name - Drop reference on "struct cs_name".
+ *
+ * @name: Pointer to "struct cs_path_info". Maybe NULL.
+ *
+ * Returns nothing.
+ */
+static inline void cs_put_name(const struct cs_path_info *name)
+{
+	if (name)
+		atomic_dec(&container_of(name, struct cs_name, entry)->
+			   head.users);
+}
+
+/*
+ * Structure for holding "struct cs_domain_info *" and "u32 cs_flags" for
+ * each "struct task_struct".
+ *
+ * "struct cs_domain_info *" and "u32 cs_flags" for each "struct task_struct"
+ * are maintained outside that "struct task_struct". Therefore, cs_security
+ * != task_struct . This keeps KABI for distributor's prebuilt kernels but
+ * entails slow access.
+ *
+ * Memory for this structure is allocated when current thread tries to access
+ * it. Therefore, if memory allocation failed, current thread will be killed by
+ * SIGKILL. Note that if current->pid == 1, sending SIGKILL won't work.
+ */
+struct cs_security {
+	struct list_head list;
+	const struct task_struct *task;
+	struct cs_domain_info *cs_domain_info;
+	u32 cs_flags;
+	struct cs_request_info *r; /* Maybe NULL. */
+	struct rcu_head rcu;
+};
+
+void __init cs_main_init(void);
+bool cs_used_by_cred(const struct cs_domain_info *domain);
+int cs_start_execve(struct linux_binprm *bprm, struct cs_request_info **rp);
+void cs_finish_execve(int retval, struct cs_request_info *r);
+int cs_sysctl_permission(enum cs_mac_index type,
+			 const struct cs_path_info *filename);
+
+#define CS_TASK_SECURITY_HASH_BITS 12
+#define CS_MAX_TASK_SECURITY_HASH (1u << CS_TASK_SECURITY_HASH_BITS)
+extern struct list_head cs_task_security_list[CS_MAX_TASK_SECURITY_HASH];
+
+struct cs_security *cs_find_task_security(const struct task_struct *task);
+
+/**
+ * cs_current_security - Get "struct cs_security" for current thread.
+ *
+ * Returns pointer to "struct cs_security" for current thread.
+ */
+static inline struct cs_security *cs_current_security(void)
+{
+	return cs_find_task_security(current);
+}
+
+/**
+ * cs_task_domain - Get "struct cs_domain_info" for specified thread.
+ *
+ * @task: Pointer to "struct task_struct".
+ *
+ * Returns pointer to "struct cs_security" for specified thread.
+ */
+static inline struct cs_domain_info *cs_task_domain(struct task_struct *task)
+{
+	struct cs_domain_info *domain;
+
+	rcu_read_lock();
+	domain = cs_find_task_security(task)->cs_domain_info;
+	rcu_read_unlock();
+	return domain;
+}
+
+/**
+ * cs_current_domain - Get "struct cs_domain_info" for current thread.
+ *
+ * Returns pointer to "struct cs_domain_info" for current thread.
+ */
+static inline struct cs_domain_info *cs_current_domain(void)
+{
+	return cs_find_task_security(current)->cs_domain_info;
+}
+
+/**
+ * cs_task_flags - Get flags for specified thread.
+ *
+ * @task: Pointer to "struct task_struct".
+ *
+ * Returns flags for specified thread.
+ */
+static inline u32 cs_task_flags(struct task_struct *task)
+{
+	u32 cs_flags;
+
+	rcu_read_lock();
+	cs_flags = cs_find_task_security(task)->cs_flags;
+	rcu_read_unlock();
+	return cs_flags;
+}
+
+/**
+ * cs_current_flags - Get flags for current thread.
+ *
+ * Returns flags for current thread.
+ */
+static inline u32 cs_current_flags(void)
+{
+	return cs_find_task_security(current)->cs_flags;
+}
+
+#endif
-- 
2.18.4



More information about the Linux-security-module-archive mailing list