diff options
Diffstat (limited to 'security/selinux/include')
| -rw-r--r-- | security/selinux/include/audit.h | 76 | ||||
| -rw-r--r-- | security/selinux/include/avc.h | 79 | ||||
| -rw-r--r-- | security/selinux/include/avc_ss.h | 15 | ||||
| -rw-r--r-- | security/selinux/include/classmap.h | 286 | ||||
| -rw-r--r-- | security/selinux/include/conditional.h | 13 | ||||
| -rw-r--r-- | security/selinux/include/hash.h | 47 | ||||
| -rw-r--r-- | security/selinux/include/ibpkey.h | 35 | ||||
| -rw-r--r-- | security/selinux/include/ima.h | 28 | ||||
| -rw-r--r-- | security/selinux/include/initcalls.h | 19 | ||||
| -rw-r--r-- | security/selinux/include/initial_sid_to_string.h | 69 | ||||
| -rw-r--r-- | security/selinux/include/netif.h | 13 | ||||
| -rw-r--r-- | security/selinux/include/netlabel.h | 88 | ||||
| -rw-r--r-- | security/selinux/include/netnode.h | 18 | ||||
| -rw-r--r-- | security/selinux/include/netport.h | 16 | ||||
| -rw-r--r-- | security/selinux/include/objsec.h | 261 | ||||
| -rw-r--r-- | security/selinux/include/policycap.h | 28 | ||||
| -rw-r--r-- | security/selinux/include/policycap_names.h | 28 | ||||
| -rw-r--r-- | security/selinux/include/security.h | 394 | ||||
| -rw-r--r-- | security/selinux/include/xfrm.h | 63 |
19 files changed, 1051 insertions, 525 deletions
diff --git a/security/selinux/include/audit.h b/security/selinux/include/audit.h index 1bdf973433cc..85a531ac737b 100644 --- a/security/selinux/include/audit.h +++ b/security/selinux/include/audit.h @@ -1,65 +1,71 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * SELinux support for the Audit LSM hooks * - * Most of below header was moved from include/linux/selinux.h which - * is released under below copyrights: - * * Author: James Morris <jmorris@redhat.com> * * Copyright (C) 2005 Red Hat, Inc., James Morris <jmorris@redhat.com> * Copyright (C) 2006 Trusted Computer Solutions, Inc. <dgoeddel@trustedcs.com> * Copyright (C) 2006 IBM Corporation, Timothy R. Chavez <tinytim@us.ibm.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2, - * as published by the Free Software Foundation. */ #ifndef _SELINUX_AUDIT_H #define _SELINUX_AUDIT_H +#include <linux/audit.h> +#include <linux/types.h> + +/** + * selinux_audit_rule_avc_callback - update the audit LSM rules on AVC events. + * @event: the AVC event + * + * Update any audit LSM rules based on the AVC event specified in @event. + * Returns 0 on success, negative values otherwise. + */ +int selinux_audit_rule_avc_callback(u32 event); + /** - * selinux_audit_rule_init - alloc/init an selinux audit rule structure. - * @field: the field this rule refers to - * @op: the operater the rule uses - * @rulestr: the text "target" of the rule - * @rule: pointer to the new rule structure returned via this + * selinux_audit_rule_init - alloc/init an selinux audit rule structure. + * @field: the field this rule refers to + * @op: the operator the rule uses + * @rulestr: the text "target" of the rule + * @rule: pointer to the new rule structure returned via this + * @gfp: GFP flag used for kmalloc * - * Returns 0 if successful, -errno if not. On success, the rule structure - * will be allocated internally. The caller must free this structure with - * selinux_audit_rule_free() after use. + * Returns 0 if successful, -errno if not. On success, the rule structure + * will be allocated internally. The caller must free this structure with + * selinux_audit_rule_free() after use. */ -int selinux_audit_rule_init(u32 field, u32 op, char *rulestr, void **rule); +int selinux_audit_rule_init(u32 field, u32 op, char *rulestr, void **rule, + gfp_t gfp); /** - * selinux_audit_rule_free - free an selinux audit rule structure. - * @rule: pointer to the audit rule to be freed + * selinux_audit_rule_free - free an selinux audit rule structure. + * @rule: pointer to the audit rule to be freed * - * This will free all memory associated with the given rule. - * If @rule is NULL, no operation is performed. + * This will free all memory associated with the given rule. + * If @rule is NULL, no operation is performed. */ void selinux_audit_rule_free(void *rule); /** - * selinux_audit_rule_match - determine if a context ID matches a rule. - * @sid: the context ID to check - * @field: the field this rule refers to - * @op: the operater the rule uses - * @rule: pointer to the audit rule to check against - * @actx: the audit context (can be NULL) associated with the check + * selinux_audit_rule_match - determine if a context ID matches a rule. + * @prop: includes the context ID to check + * @field: the field this rule refers to + * @op: the operator the rule uses + * @rule: pointer to the audit rule to check against * - * Returns 1 if the context id matches the rule, 0 if it does not, and - * -errno on failure. + * Returns 1 if the context id matches the rule, 0 if it does not, and + * -errno on failure. */ -int selinux_audit_rule_match(u32 sid, u32 field, u32 op, void *rule, - struct audit_context *actx); +int selinux_audit_rule_match(struct lsm_prop *prop, u32 field, u32 op, + void *rule); /** - * selinux_audit_rule_known - check to see if rule contains selinux fields. - * @rule: rule to be checked - * Returns 1 if there are selinux fields specified in the rule, 0 otherwise. + * selinux_audit_rule_known - check to see if rule contains selinux fields. + * @rule: rule to be checked + * Returns 1 if there are selinux fields specified in the rule, 0 otherwise. */ -int selinux_audit_rule_known(struct audit_krule *krule); +int selinux_audit_rule_known(struct audit_krule *rule); #endif /* _SELINUX_AUDIT_H */ - diff --git a/security/selinux/include/avc.h b/security/selinux/include/avc.h index 92d0ab561db8..01b5167fee1a 100644 --- a/security/selinux/include/avc.h +++ b/security/selinux/include/avc.h @@ -1,8 +1,10 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Access vector cache interface for object managers. * - * Author : Stephen Smalley, <sds@epoch.ncsc.mil> + * Author : Stephen Smalley, <stephen.smalley.work@gmail.com> */ + #ifndef _SELINUX_AVC_H_ #define _SELINUX_AVC_H_ @@ -19,12 +21,6 @@ #include "av_permissions.h" #include "security.h" -#ifdef CONFIG_SECURITY_SELINUX_DEVELOP -extern int selinux_enforcing; -#else -#define selinux_enforcing 1 -#endif - /* * An entry in the AVC. */ @@ -57,7 +53,7 @@ struct selinux_audit_data { u32 audited; u32 denied; int result; -}; +} __randomize_layout; /* * AVC operations @@ -65,13 +61,14 @@ struct selinux_audit_data { void __init avc_init(void); -static inline u32 avc_audit_required(u32 requested, - struct av_decision *avd, - int result, - u32 auditdeny, - u32 *deniedp) +static inline u32 avc_audit_required(u32 requested, struct av_decision *avd, + int result, u32 auditdeny, u32 *deniedp) { u32 denied, audited; + + if (avd->flags & AVD_FLAGS_NEVERAUDIT) + return 0; + denied = requested & ~avd->allowed; if (unlikely(denied)) { audited = denied & avd->auditdeny; @@ -101,10 +98,8 @@ static inline u32 avc_audit_required(u32 requested, return audited; } -int slow_avc_audit(u32 ssid, u32 tsid, u16 tclass, - u32 requested, u32 audited, u32 denied, - struct common_audit_data *a, - unsigned flags); +int slow_avc_audit(u32 ssid, u32 tsid, u16 tclass, u32 requested, u32 audited, + u32 denied, int result, struct common_audit_data *a); /** * avc_audit - Audit the granting or denial of permissions. @@ -115,7 +110,6 @@ int slow_avc_audit(u32 ssid, u32 tsid, u16 tclass, * @avd: access vector decisions * @result: result from avc_has_perm_noaudit * @a: auxiliary audit data - * @flags: VFS walk flags * * Audit the granting or denial of permissions in accordance * with the policy. This function is typically called by @@ -126,38 +120,31 @@ int slow_avc_audit(u32 ssid, u32 tsid, u16 tclass, * be performed under a lock, to allow the lock to be released * before calling the auditing code. */ -static inline int avc_audit(u32 ssid, u32 tsid, - u16 tclass, u32 requested, - struct av_decision *avd, - int result, - struct common_audit_data *a, unsigned flags) +static inline int avc_audit(u32 ssid, u32 tsid, u16 tclass, u32 requested, + struct av_decision *avd, int result, + struct common_audit_data *a) { u32 audited, denied; audited = avc_audit_required(requested, avd, result, 0, &denied); if (likely(!audited)) return 0; - return slow_avc_audit(ssid, tsid, tclass, - requested, audited, denied, - a, flags); + return slow_avc_audit(ssid, tsid, tclass, requested, audited, denied, + result, a); } -#define AVC_STRICT 1 /* Ignore permissive mode. */ -int avc_has_perm_noaudit(u32 ssid, u32 tsid, - u16 tclass, u32 requested, - unsigned flags, - struct av_decision *avd); +#define AVC_STRICT 1 /* Ignore permissive mode. */ +#define AVC_EXTENDED_PERMS 2 /* update extended permissions */ +int avc_has_perm_noaudit(u32 ssid, u32 tsid, u16 tclass, u32 requested, + unsigned int flags, struct av_decision *avd); -int avc_has_perm_flags(u32 ssid, u32 tsid, - u16 tclass, u32 requested, - struct common_audit_data *auditdata, - unsigned); +int avc_has_perm(u32 ssid, u32 tsid, u16 tclass, u32 requested, + struct common_audit_data *auditdata); -static inline int avc_has_perm(u32 ssid, u32 tsid, - u16 tclass, u32 requested, - struct common_audit_data *auditdata) -{ - return avc_has_perm_flags(ssid, tsid, tclass, requested, auditdata, 0); -} +#define AVC_EXT_IOCTL (1 << 0) /* Cache entry for an ioctl extended permission */ +#define AVC_EXT_NLMSG (1 << 1) /* Cache entry for an nlmsg extended permission */ +int avc_has_extended_perms(u32 ssid, u32 tsid, u16 tclass, u32 requested, + u8 driver, u8 base_perm, u8 perm, + struct common_audit_data *ad); u32 avc_policy_seqno(void); @@ -166,22 +153,20 @@ u32 avc_policy_seqno(void); #define AVC_CALLBACK_REVOKE 4 #define AVC_CALLBACK_RESET 8 #define AVC_CALLBACK_AUDITALLOW_ENABLE 16 -#define AVC_CALLBACK_AUDITALLOW_DISABLE 32 +#define AVC_CALLBACK_AUDITALLOW_DISABLE 32 #define AVC_CALLBACK_AUDITDENY_ENABLE 64 #define AVC_CALLBACK_AUDITDENY_DISABLE 128 +#define AVC_CALLBACK_ADD_XPERMS 256 int avc_add_callback(int (*callback)(u32 event), u32 events); /* Exported to selinuxfs */ int avc_get_hash_stats(char *page); -extern unsigned int avc_cache_threshold; - -/* Attempt to free avc node cache */ -void avc_disable(void); +unsigned int avc_get_cache_threshold(void); +void avc_set_cache_threshold(unsigned int cache_threshold); #ifdef CONFIG_SECURITY_SELINUX_AVC_STATS DECLARE_PER_CPU(struct avc_cache_stats, avc_cache_stats); #endif #endif /* _SELINUX_AVC_H_ */ - diff --git a/security/selinux/include/avc_ss.h b/security/selinux/include/avc_ss.h index d5c328452df0..48ad64d54032 100644 --- a/security/selinux/include/avc_ss.h +++ b/security/selinux/include/avc_ss.h @@ -1,12 +1,14 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Access vector cache interface for the security server. * - * Author : Stephen Smalley, <sds@epoch.ncsc.mil> + * Author : Stephen Smalley, <stephen.smalley.work@gmail.com> */ + #ifndef _SELINUX_AVC_SS_H_ #define _SELINUX_AVC_SS_H_ -#include "flask.h" +#include <linux/types.h> int avc_ss_reset(u32 seqno); @@ -16,13 +18,6 @@ struct security_class_mapping { const char *perms[sizeof(u32) * 8 + 1]; }; -extern struct security_class_mapping secclass_map[]; - -/* - * The security server must be initialized before - * any labeling or access decisions can be provided. - */ -extern int ss_initialized; +extern const struct security_class_mapping secclass_map[]; #endif /* _SELINUX_AVC_SS_H_ */ - diff --git a/security/selinux/include/classmap.h b/security/selinux/include/classmap.h index 14d04e63b1f0..3ec85142771f 100644 --- a/security/selinux/include/classmap.h +++ b/security/selinux/include/classmap.h @@ -1,155 +1,193 @@ -#define COMMON_FILE_SOCK_PERMS "ioctl", "read", "write", "create", \ - "getattr", "setattr", "lock", "relabelfrom", "relabelto", "append" +/* SPDX-License-Identifier: GPL-2.0 */ -#define COMMON_FILE_PERMS COMMON_FILE_SOCK_PERMS, "unlink", "link", \ - "rename", "execute", "swapon", "quotaon", "mounton", "audit_access", \ - "open", "execmod" +#define COMMON_FILE_SOCK_PERMS \ + "ioctl", "read", "write", "create", "getattr", "setattr", "lock", \ + "relabelfrom", "relabelto", "append", "map" -#define COMMON_SOCK_PERMS COMMON_FILE_SOCK_PERMS, "bind", "connect", \ - "listen", "accept", "getopt", "setopt", "shutdown", "recvfrom", \ - "sendto", "recv_msg", "send_msg", "name_bind" +#define COMMON_FILE_PERMS \ + COMMON_FILE_SOCK_PERMS, "unlink", "link", "rename", "execute", \ + "quotaon", "mounton", "audit_access", "open", "execmod", \ + "watch", "watch_mount", "watch_sb", "watch_with_perm", \ + "watch_reads", "watch_mountns" -#define COMMON_IPC_PERMS "create", "destroy", "getattr", "setattr", "read", \ - "write", "associate", "unix_read", "unix_write" +#define COMMON_SOCK_PERMS \ + COMMON_FILE_SOCK_PERMS, "bind", "connect", "listen", "accept", \ + "getopt", "setopt", "shutdown", "recvfrom", "sendto", \ + "name_bind" + +#define COMMON_IPC_PERMS \ + "create", "destroy", "getattr", "setattr", "read", "write", \ + "associate", "unix_read", "unix_write" + +#define COMMON_CAP_PERMS \ + "chown", "dac_override", "dac_read_search", "fowner", "fsetid", \ + "kill", "setgid", "setuid", "setpcap", "linux_immutable", \ + "net_bind_service", "net_broadcast", "net_admin", "net_raw", \ + "ipc_lock", "ipc_owner", "sys_module", "sys_rawio", \ + "sys_chroot", "sys_ptrace", "sys_pacct", "sys_admin", \ + "sys_boot", "sys_nice", "sys_resource", "sys_time", \ + "sys_tty_config", "mknod", "lease", "audit_write", \ + "audit_control", "setfcap" + +#define COMMON_CAP2_PERMS \ + "mac_override", "mac_admin", "syslog", "wake_alarm", "block_suspend", \ + "audit_read", "perfmon", "bpf", "checkpoint_restore" + +#ifdef __KERNEL__ /* avoid this check when building host programs */ +#include <linux/capability.h> + +#if CAP_LAST_CAP > CAP_CHECKPOINT_RESTORE +#error New capability defined, please update COMMON_CAP2_PERMS. +#endif +#endif /* * Note: The name for any socket class should be suffixed by "socket", * and doesn't contain more than one substr of "socket". */ -struct security_class_mapping secclass_map[] = { +const struct security_class_mapping secclass_map[] = { { "security", - { "compute_av", "compute_create", "compute_member", - "check_context", "load_policy", "compute_relabel", - "compute_user", "setenforce", "setbool", "setsecparam", - "setcheckreqprot", "read_policy", NULL } }, + { "compute_av", "compute_create", "compute_member", "check_context", + "load_policy", "compute_relabel", "compute_user", "setenforce", + "setbool", "setsecparam", "setcheckreqprot", "read_policy", + "validate_trans", NULL } }, { "process", - { "fork", "transition", "sigchld", "sigkill", - "sigstop", "signull", "signal", "ptrace", "getsched", "setsched", - "getsession", "getpgid", "setpgid", "getcap", "setcap", "share", - "getattr", "setexec", "setfscreate", "noatsecure", "siginh", - "setrlimit", "rlimitinh", "dyntransition", "setcurrent", - "execmem", "execstack", "execheap", "setkeycreate", - "setsockcreate", NULL } }, + { "fork", "transition", "sigchld", "sigkill", + "sigstop", "signull", "signal", "ptrace", + "getsched", "setsched", "getsession", "getpgid", + "setpgid", "getcap", "setcap", "share", + "getattr", "setexec", "setfscreate", "noatsecure", + "siginh", "setrlimit", "rlimitinh", "dyntransition", + "setcurrent", "execmem", "execstack", "execheap", + "setkeycreate", "setsockcreate", "getrlimit", NULL } }, + { "process2", { "nnp_transition", "nosuid_transition", NULL } }, { "system", - { "ipc_info", "syslog_read", "syslog_mod", - "syslog_console", "module_request", NULL } }, - { "capability", - { "chown", "dac_override", "dac_read_search", - "fowner", "fsetid", "kill", "setgid", "setuid", "setpcap", - "linux_immutable", "net_bind_service", "net_broadcast", - "net_admin", "net_raw", "ipc_lock", "ipc_owner", "sys_module", - "sys_rawio", "sys_chroot", "sys_ptrace", "sys_pacct", "sys_admin", - "sys_boot", "sys_nice", "sys_resource", "sys_time", - "sys_tty_config", "mknod", "lease", "audit_write", - "audit_control", "setfcap", NULL } }, + { "ipc_info", "syslog_read", "syslog_mod", "syslog_console", + "module_request", "module_load", "firmware_load", + "kexec_image_load", "kexec_initramfs_load", "policy_load", + "x509_certificate_load", NULL } }, + { "capability", { COMMON_CAP_PERMS, NULL } }, { "filesystem", - { "mount", "remount", "unmount", "getattr", - "relabelfrom", "relabelto", "transition", "associate", "quotamod", - "quotaget", NULL } }, + { "mount", "remount", "unmount", "getattr", "relabelfrom", + "relabelto", "associate", "quotamod", "quotaget", "watch", NULL } }, { "file", - { COMMON_FILE_PERMS, - "execute_no_trans", "entrypoint", NULL } }, + { COMMON_FILE_PERMS, "execute_no_trans", "entrypoint", NULL } }, { "dir", - { COMMON_FILE_PERMS, "add_name", "remove_name", - "reparent", "search", "rmdir", NULL } }, + { COMMON_FILE_PERMS, "add_name", "remove_name", "reparent", "search", + "rmdir", NULL } }, { "fd", { "use", NULL } }, - { "lnk_file", - { COMMON_FILE_PERMS, NULL } }, - { "chr_file", - { COMMON_FILE_PERMS, NULL } }, - { "blk_file", - { COMMON_FILE_PERMS, NULL } }, - { "sock_file", - { COMMON_FILE_PERMS, NULL } }, - { "fifo_file", - { COMMON_FILE_PERMS, NULL } }, - { "socket", - { COMMON_SOCK_PERMS, NULL } }, + { "lnk_file", { COMMON_FILE_PERMS, NULL } }, + { "chr_file", { COMMON_FILE_PERMS, NULL } }, + { "blk_file", { COMMON_FILE_PERMS, NULL } }, + { "sock_file", { COMMON_FILE_PERMS, NULL } }, + { "fifo_file", { COMMON_FILE_PERMS, NULL } }, + { "socket", { COMMON_SOCK_PERMS, NULL } }, { "tcp_socket", - { COMMON_SOCK_PERMS, - "connectto", "newconn", "acceptfrom", "node_bind", "name_connect", - NULL } }, - { "udp_socket", - { COMMON_SOCK_PERMS, - "node_bind", NULL } }, - { "rawip_socket", - { COMMON_SOCK_PERMS, - "node_bind", NULL } }, - { "node", - { "tcp_recv", "tcp_send", "udp_recv", "udp_send", - "rawip_recv", "rawip_send", "enforce_dest", - "dccp_recv", "dccp_send", "recvfrom", "sendto", NULL } }, - { "netif", - { "tcp_recv", "tcp_send", "udp_recv", "udp_send", - "rawip_recv", "rawip_send", "dccp_recv", "dccp_send", - "ingress", "egress", NULL } }, - { "netlink_socket", - { COMMON_SOCK_PERMS, NULL } }, - { "packet_socket", - { COMMON_SOCK_PERMS, NULL } }, - { "key_socket", - { COMMON_SOCK_PERMS, NULL } }, - { "unix_stream_socket", - { COMMON_SOCK_PERMS, "connectto", "newconn", "acceptfrom", NULL - } }, - { "unix_dgram_socket", - { COMMON_SOCK_PERMS, NULL - } }, - { "sem", - { COMMON_IPC_PERMS, NULL } }, + { COMMON_SOCK_PERMS, "node_bind", "name_connect", NULL } }, + { "udp_socket", { COMMON_SOCK_PERMS, "node_bind", NULL } }, + { "rawip_socket", { COMMON_SOCK_PERMS, "node_bind", NULL } }, + { "node", { "recvfrom", "sendto", NULL } }, + { "netif", { "ingress", "egress", NULL } }, + { "netlink_socket", { COMMON_SOCK_PERMS, NULL } }, + { "packet_socket", { COMMON_SOCK_PERMS, NULL } }, + { "key_socket", { COMMON_SOCK_PERMS, NULL } }, + { "unix_stream_socket", { COMMON_SOCK_PERMS, "connectto", NULL } }, + { "unix_dgram_socket", { COMMON_SOCK_PERMS, NULL } }, + { "sem", { COMMON_IPC_PERMS, NULL } }, { "msg", { "send", "receive", NULL } }, - { "msgq", - { COMMON_IPC_PERMS, "enqueue", NULL } }, - { "shm", - { COMMON_IPC_PERMS, "lock", NULL } }, - { "ipc", - { COMMON_IPC_PERMS, NULL } }, + { "msgq", { COMMON_IPC_PERMS, "enqueue", NULL } }, + { "shm", { COMMON_IPC_PERMS, "lock", NULL } }, + { "ipc", { COMMON_IPC_PERMS, NULL } }, { "netlink_route_socket", - { COMMON_SOCK_PERMS, - "nlmsg_read", "nlmsg_write", NULL } }, - { "netlink_firewall_socket", - { COMMON_SOCK_PERMS, - "nlmsg_read", "nlmsg_write", NULL } }, + { COMMON_SOCK_PERMS, "nlmsg_read", "nlmsg_write", "nlmsg", NULL } }, { "netlink_tcpdiag_socket", - { COMMON_SOCK_PERMS, - "nlmsg_read", "nlmsg_write", NULL } }, - { "netlink_nflog_socket", - { COMMON_SOCK_PERMS, NULL } }, + { COMMON_SOCK_PERMS, "nlmsg_read", "nlmsg_write", "nlmsg", NULL } }, + { "netlink_nflog_socket", { COMMON_SOCK_PERMS, NULL } }, { "netlink_xfrm_socket", - { COMMON_SOCK_PERMS, - "nlmsg_read", "nlmsg_write", NULL } }, - { "netlink_selinux_socket", - { COMMON_SOCK_PERMS, NULL } }, + { COMMON_SOCK_PERMS, "nlmsg_read", "nlmsg_write", "nlmsg", NULL } }, + { "netlink_selinux_socket", { COMMON_SOCK_PERMS, NULL } }, + { "netlink_iscsi_socket", { COMMON_SOCK_PERMS, NULL } }, { "netlink_audit_socket", - { COMMON_SOCK_PERMS, - "nlmsg_read", "nlmsg_write", "nlmsg_relay", "nlmsg_readpriv", - "nlmsg_tty_audit", NULL } }, - { "netlink_ip6fw_socket", - { COMMON_SOCK_PERMS, - "nlmsg_read", "nlmsg_write", NULL } }, - { "netlink_dnrt_socket", - { COMMON_SOCK_PERMS, NULL } }, + { COMMON_SOCK_PERMS, "nlmsg_read", "nlmsg_write", "nlmsg_relay", + "nlmsg_readpriv", "nlmsg_tty_audit", "nlmsg", NULL } }, + { "netlink_fib_lookup_socket", { COMMON_SOCK_PERMS, NULL } }, + { "netlink_connector_socket", { COMMON_SOCK_PERMS, NULL } }, + { "netlink_netfilter_socket", { COMMON_SOCK_PERMS, NULL } }, + { "netlink_dnrt_socket", { COMMON_SOCK_PERMS, NULL } }, { "association", { "sendto", "recvfrom", "setcontext", "polmatch", NULL } }, - { "netlink_kobject_uevent_socket", - { COMMON_SOCK_PERMS, NULL } }, - { "appletalk_socket", - { COMMON_SOCK_PERMS, NULL } }, + { "netlink_kobject_uevent_socket", { COMMON_SOCK_PERMS, NULL } }, + { "netlink_generic_socket", { COMMON_SOCK_PERMS, NULL } }, + { "netlink_scsitransport_socket", { COMMON_SOCK_PERMS, NULL } }, + { "netlink_rdma_socket", { COMMON_SOCK_PERMS, NULL } }, + { "netlink_crypto_socket", { COMMON_SOCK_PERMS, NULL } }, + { "appletalk_socket", { COMMON_SOCK_PERMS, NULL } }, { "packet", { "send", "recv", "relabelto", "forward_in", "forward_out", NULL } }, { "key", { "view", "read", "write", "search", "link", "setattr", "create", NULL } }, - { "dccp_socket", - { COMMON_SOCK_PERMS, - "node_bind", "name_connect", NULL } }, { "memprotect", { "mmap_zero", NULL } }, { "peer", { "recv", NULL } }, - { "capability2", - { "mac_override", "mac_admin", "syslog", "wake_alarm", "block_suspend", - NULL } }, + { "capability2", { COMMON_CAP2_PERMS, NULL } }, { "kernel_service", { "use_as_override", "create_files_as", NULL } }, - { "tun_socket", - { COMMON_SOCK_PERMS, "attach_queue", NULL } }, - { NULL } - }; + { "tun_socket", { COMMON_SOCK_PERMS, "attach_queue", NULL } }, + { "binder", + { "impersonate", "call", "set_context_mgr", "transfer", NULL } }, + { "cap_userns", { COMMON_CAP_PERMS, NULL } }, + { "cap2_userns", { COMMON_CAP2_PERMS, NULL } }, + { "sctp_socket", + { COMMON_SOCK_PERMS, "node_bind", "name_connect", "association", + NULL } }, + { "icmp_socket", { COMMON_SOCK_PERMS, "node_bind", NULL } }, + { "ax25_socket", { COMMON_SOCK_PERMS, NULL } }, + { "ipx_socket", { COMMON_SOCK_PERMS, NULL } }, + { "netrom_socket", { COMMON_SOCK_PERMS, NULL } }, + { "atmpvc_socket", { COMMON_SOCK_PERMS, NULL } }, + { "x25_socket", { COMMON_SOCK_PERMS, NULL } }, + { "rose_socket", { COMMON_SOCK_PERMS, NULL } }, + { "decnet_socket", { COMMON_SOCK_PERMS, NULL } }, + { "atmsvc_socket", { COMMON_SOCK_PERMS, NULL } }, + { "rds_socket", { COMMON_SOCK_PERMS, NULL } }, + { "irda_socket", { COMMON_SOCK_PERMS, NULL } }, + { "pppox_socket", { COMMON_SOCK_PERMS, NULL } }, + { "llc_socket", { COMMON_SOCK_PERMS, NULL } }, + { "can_socket", { COMMON_SOCK_PERMS, NULL } }, + { "tipc_socket", { COMMON_SOCK_PERMS, NULL } }, + { "bluetooth_socket", { COMMON_SOCK_PERMS, NULL } }, + { "iucv_socket", { COMMON_SOCK_PERMS, NULL } }, + { "rxrpc_socket", { COMMON_SOCK_PERMS, NULL } }, + { "isdn_socket", { COMMON_SOCK_PERMS, NULL } }, + { "phonet_socket", { COMMON_SOCK_PERMS, NULL } }, + { "ieee802154_socket", { COMMON_SOCK_PERMS, NULL } }, + { "caif_socket", { COMMON_SOCK_PERMS, NULL } }, + { "alg_socket", { COMMON_SOCK_PERMS, NULL } }, + { "nfc_socket", { COMMON_SOCK_PERMS, NULL } }, + { "vsock_socket", { COMMON_SOCK_PERMS, NULL } }, + { "kcm_socket", { COMMON_SOCK_PERMS, NULL } }, + { "qipcrtr_socket", { COMMON_SOCK_PERMS, NULL } }, + { "smc_socket", { COMMON_SOCK_PERMS, NULL } }, + { "infiniband_pkey", { "access", NULL } }, + { "infiniband_endport", { "manage_subnet", NULL } }, + { "bpf", + { "map_create", "map_read", "map_write", "prog_load", "prog_run", + NULL } }, + { "xdp_socket", { COMMON_SOCK_PERMS, NULL } }, + { "mctp_socket", { COMMON_SOCK_PERMS, NULL } }, + { "perf_event", + { "open", "cpu", "kernel", "tracepoint", "read", "write", NULL } }, + { "anon_inode", { COMMON_FILE_PERMS, NULL } }, + { "io_uring", { "override_creds", "sqpoll", "cmd", "allowed", NULL } }, + { "user_namespace", { "create", NULL } }, + { "memfd_file", + { COMMON_FILE_PERMS, "execute_no_trans", "entrypoint", NULL } }, + /* last one */ { NULL, {} } +}; + +#ifdef __KERNEL__ /* avoid this check when building host programs */ +#include <linux/socket.h> + +#if PF_MAX > 46 +#error New address family defined, please update secclass_map. +#endif +#endif diff --git a/security/selinux/include/conditional.h b/security/selinux/include/conditional.h index 67ce7a8d8301..060833e2dba2 100644 --- a/security/selinux/include/conditional.h +++ b/security/selinux/include/conditional.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Interface to booleans in the security server. This is exported * for the selinuxfs. @@ -5,18 +6,18 @@ * Author: Karl MacMillan <kmacmillan@tresys.com> * * Copyright (C) 2003 - 2004 Tresys Technology, LLC - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, version 2. */ #ifndef _SELINUX_CONDITIONAL_H_ #define _SELINUX_CONDITIONAL_H_ -int security_get_bools(int *len, char ***names, int **values); +#include "security.h" -int security_set_bools(int len, int *values); +int security_get_bools(struct selinux_policy *policy, u32 *len, char ***names, + int **values); -int security_get_bool_value(int bool); +int security_set_bools(u32 len, const int *values); + +int security_get_bool_value(u32 index); #endif diff --git a/security/selinux/include/hash.h b/security/selinux/include/hash.h new file mode 100644 index 000000000000..18956dbef8ff --- /dev/null +++ b/security/selinux/include/hash.h @@ -0,0 +1,47 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef _SELINUX_HASH_H_ +#define _SELINUX_HASH_H_ + +/* + * Based on MurmurHash3, written by Austin Appleby and placed in the + * public domain. + */ +static inline u32 av_hash(u32 key1, u32 key2, u32 key3, u32 mask) +{ + static const u32 c1 = 0xcc9e2d51; + static const u32 c2 = 0x1b873593; + static const u32 r1 = 15; + static const u32 r2 = 13; + static const u32 m = 5; + static const u32 n = 0xe6546b64; + + u32 hash = 0; + +#define mix(input) \ + do { \ + u32 v = input; \ + v *= c1; \ + v = (v << r1) | (v >> (32 - r1)); \ + v *= c2; \ + hash ^= v; \ + hash = (hash << r2) | (hash >> (32 - r2)); \ + hash = hash * m + n; \ + } while (0) + + mix(key1); + mix(key2); + mix(key3); + +#undef mix + + hash ^= hash >> 16; + hash *= 0x85ebca6b; + hash ^= hash >> 13; + hash *= 0xc2b2ae35; + hash ^= hash >> 16; + + return hash & mask; +} + +#endif /* _SELINUX_HASH_H_ */ diff --git a/security/selinux/include/ibpkey.h b/security/selinux/include/ibpkey.h new file mode 100644 index 000000000000..875b055849e1 --- /dev/null +++ b/security/selinux/include/ibpkey.h @@ -0,0 +1,35 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * pkey table + * + * SELinux must keep a mapping of pkeys to labels/SIDs. This + * mapping is maintained as part of the normal policy but a fast cache is + * needed to reduce the lookup overhead. + */ + +/* + * (c) Mellanox Technologies, 2016 + */ + +#ifndef _SELINUX_IB_PKEY_H +#define _SELINUX_IB_PKEY_H + +#include <linux/types.h> +#include "flask.h" + +#ifdef CONFIG_SECURITY_INFINIBAND +void sel_ib_pkey_flush(void); +int sel_ib_pkey_sid(u64 subnet_prefix, u16 pkey, u32 *sid); +#else +static inline void sel_ib_pkey_flush(void) +{ + return; +} +static inline int sel_ib_pkey_sid(u64 subnet_prefix, u16 pkey, u32 *sid) +{ + *sid = SECINITSID_UNLABELED; + return 0; +} +#endif + +#endif diff --git a/security/selinux/include/ima.h b/security/selinux/include/ima.h new file mode 100644 index 000000000000..38ab302f5946 --- /dev/null +++ b/security/selinux/include/ima.h @@ -0,0 +1,28 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2021 Microsoft Corporation + * + * Author: Lakshmi Ramasubramanian (nramas@linux.microsoft.com) + * + * Measure critical data structures maintained by SELinux + * using IMA subsystem. + */ + +#ifndef _SELINUX_IMA_H_ +#define _SELINUX_IMA_H_ + +#include "security.h" + +#ifdef CONFIG_IMA +extern void selinux_ima_measure_state(void); +extern void selinux_ima_measure_state_locked(void); +#else +static inline void selinux_ima_measure_state(void) +{ +} +static inline void selinux_ima_measure_state_locked(void) +{ +} +#endif + +#endif /* _SELINUX_IMA_H_ */ diff --git a/security/selinux/include/initcalls.h b/security/selinux/include/initcalls.h new file mode 100644 index 000000000000..6674cf489473 --- /dev/null +++ b/security/selinux/include/initcalls.h @@ -0,0 +1,19 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * SELinux initcalls + */ + +#ifndef _SELINUX_INITCALLS_H +#define _SELINUX_INITCALLS_H + +int init_sel_fs(void); +int sel_netport_init(void); +int sel_netnode_init(void); +int sel_netif_init(void); +int sel_netlink_init(void); +int sel_ib_pkey_init(void); +int selinux_nf_ip_init(void); + +int selinux_initcall(void); + +#endif diff --git a/security/selinux/include/initial_sid_to_string.h b/security/selinux/include/initial_sid_to_string.h index a59b64e3fd02..d7ba60b62491 100644 --- a/security/selinux/include/initial_sid_to_string.h +++ b/security/selinux/include/initial_sid_to_string.h @@ -1,33 +1,38 @@ -/* This file is automatically generated. Do not edit. */ -static const char *initial_sid_to_string[] = -{ - "null", - "kernel", - "security", - "unlabeled", - "fs", - "file", - "file_labels", - "init", - "any_socket", - "port", - "netif", - "netmsg", - "node", - "igmp_packet", - "icmp_socket", - "tcp_socket", - "sysctl_modprobe", - "sysctl", - "sysctl_fs", - "sysctl_kernel", - "sysctl_net", - "sysctl_net_unix", - "sysctl_vm", - "sysctl_dev", - "kmod", - "policy", - "scmp_packet", - "devnull", -}; +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifdef __KERNEL__ +#include <linux/stddef.h> +#else +#include <stddef.h> +#endif +static const char *const initial_sid_to_string[] = { + NULL, /* zero placeholder, not used */ + "kernel", /* kernel / SECINITSID_KERNEL */ + "security", /* security / SECINITSID_SECURITY */ + "unlabeled", /* unlabeled / SECINITSID_UNLABELED */ + NULL, /* fs */ + "file", /* file / SECINITSID_FILE */ + NULL, /* file_labels */ + "init", /* init / SECINITSID_INIT */ + "any_socket", /* any_socket / SECINITSID_ANY_SOCKET */ + "port", /* port / SECINITSID_PORT */ + "netif", /* netif / SECINITSID_NETIF */ + "netmsg", /* netmsg / SECINITSID_NETMSG */ + "node", /* node / SECINITSID_NODE */ + NULL, /* igmp_packet */ + NULL, /* icmp_socket */ + NULL, /* tcp_socket */ + NULL, /* sysctl_modprobe */ + NULL, /* sysctl */ + NULL, /* sysctl_fs */ + NULL, /* sysctl_kernel */ + NULL, /* sysctl_net */ + NULL, /* sysctl_net_unix */ + NULL, /* sysctl_vm */ + NULL, /* sysctl_dev */ + NULL, /* kmod */ + NULL, /* policy */ + NULL, /* scmp_packet */ + "devnull", /* devnull / SECINITSID_DEVNULL */ +}; diff --git a/security/selinux/include/netif.h b/security/selinux/include/netif.h index 43d507242b42..2838bdc170dd 100644 --- a/security/selinux/include/netif.h +++ b/security/selinux/include/netif.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Network interface table. * @@ -9,15 +10,15 @@ * Copyright (C) 2003 Red Hat, Inc., James Morris <jmorris@redhat.com> * Copyright (C) 2007 Hewlett-Packard Development Company, L.P. * Paul Moore <paul@paul-moore.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2, - * as published by the Free Software Foundation. */ + #ifndef _SELINUX_NETIF_H_ #define _SELINUX_NETIF_H_ -int sel_netif_sid(int ifindex, u32 *sid); +#include <net/net_namespace.h> + +void sel_netif_flush(void); -#endif /* _SELINUX_NETIF_H_ */ +int sel_netif_sid(struct net *ns, int ifindex, u32 *sid); +#endif /* _SELINUX_NETIF_H_ */ diff --git a/security/selinux/include/netlabel.h b/security/selinux/include/netlabel.h index 8c59b8f150e8..5731c0dcd3e8 100644 --- a/security/selinux/include/netlabel.h +++ b/security/selinux/include/netlabel.h @@ -1,27 +1,12 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* * SELinux interface to the NetLabel subsystem * * Author: Paul Moore <paul@paul-moore.com> - * */ /* * (c) Copyright Hewlett-Packard Development Company, L.P., 2006 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See - * the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * */ #ifndef _SELINUX_NETLABEL_H_ @@ -33,6 +18,7 @@ #include <linux/skbuff.h> #include <net/sock.h> #include <net/request_sock.h> +#include <net/sctp/structs.h> #include "avc.h" #include "objsec.h" @@ -40,30 +26,29 @@ #ifdef CONFIG_NETLABEL void selinux_netlbl_cache_invalidate(void); -void selinux_netlbl_err(struct sk_buff *skb, int error, int gateway); +void selinux_netlbl_err(struct sk_buff *skb, u16 family, int error, + int gateway); void selinux_netlbl_sk_security_free(struct sk_security_struct *sksec); void selinux_netlbl_sk_security_reset(struct sk_security_struct *sksec); -int selinux_netlbl_skbuff_getsid(struct sk_buff *skb, - u16 family, - u32 *type, +int selinux_netlbl_skbuff_getsid(struct sk_buff *skb, u16 family, u32 *type, u32 *sid); -int selinux_netlbl_skbuff_setsid(struct sk_buff *skb, - u16 family, - u32 sid); - +int selinux_netlbl_skbuff_setsid(struct sk_buff *skb, u16 family, u32 sid); +int selinux_netlbl_sctp_assoc_request(struct sctp_association *asoc, + struct sk_buff *skb); int selinux_netlbl_inet_conn_request(struct request_sock *req, u16 family); void selinux_netlbl_inet_csk_clone(struct sock *sk, u16 family); +void selinux_netlbl_sctp_sk_clone(struct sock *sk, struct sock *newsk); int selinux_netlbl_socket_post_create(struct sock *sk, u16 family); int selinux_netlbl_sock_rcv_skb(struct sk_security_struct *sksec, - struct sk_buff *skb, - u16 family, + struct sk_buff *skb, u16 family, struct common_audit_data *ad); -int selinux_netlbl_socket_setsockopt(struct socket *sock, - int level, +int selinux_netlbl_socket_setsockopt(struct socket *sock, int level, int optname); int selinux_netlbl_socket_connect(struct sock *sk, struct sockaddr *addr); +int selinux_netlbl_socket_connect_locked(struct sock *sk, + struct sockaddr *addr); #else static inline void selinux_netlbl_cache_invalidate(void) @@ -71,47 +56,43 @@ static inline void selinux_netlbl_cache_invalidate(void) return; } -static inline void selinux_netlbl_err(struct sk_buff *skb, - int error, - int gateway) +static inline void selinux_netlbl_err(struct sk_buff *skb, u16 family, + int error, int gateway) { return; } -static inline void selinux_netlbl_sk_security_free( - struct sk_security_struct *sksec) +static inline void +selinux_netlbl_sk_security_free(struct sk_security_struct *sksec) { return; } -static inline void selinux_netlbl_sk_security_reset( - struct sk_security_struct *sksec) +static inline void +selinux_netlbl_sk_security_reset(struct sk_security_struct *sksec) { return; } -static inline int selinux_netlbl_skbuff_getsid(struct sk_buff *skb, - u16 family, - u32 *type, - u32 *sid) +static inline int selinux_netlbl_skbuff_getsid(struct sk_buff *skb, u16 family, + u32 *type, u32 *sid) { *type = NETLBL_NLTYPE_NONE; *sid = SECSID_NULL; return 0; } -static inline int selinux_netlbl_skbuff_setsid(struct sk_buff *skb, - u16 family, +static inline int selinux_netlbl_skbuff_setsid(struct sk_buff *skb, u16 family, u32 sid) { return 0; } -static inline int selinux_netlbl_conn_setsid(struct sock *sk, - struct sockaddr *addr) +static inline int +selinux_netlbl_sctp_assoc_request(struct sctp_association *asoc, + struct sk_buff *skb) { return 0; } - static inline int selinux_netlbl_inet_conn_request(struct request_sock *req, u16 family) { @@ -121,21 +102,23 @@ static inline void selinux_netlbl_inet_csk_clone(struct sock *sk, u16 family) { return; } -static inline int selinux_netlbl_socket_post_create(struct sock *sk, - u16 family) +static inline void selinux_netlbl_sctp_sk_clone(struct sock *sk, + struct sock *newsk) +{ + return; +} +static inline int selinux_netlbl_socket_post_create(struct sock *sk, u16 family) { return 0; } static inline int selinux_netlbl_sock_rcv_skb(struct sk_security_struct *sksec, - struct sk_buff *skb, - u16 family, + struct sk_buff *skb, u16 family, struct common_audit_data *ad) { return 0; } static inline int selinux_netlbl_socket_setsockopt(struct socket *sock, - int level, - int optname) + int level, int optname) { return 0; } @@ -144,6 +127,11 @@ static inline int selinux_netlbl_socket_connect(struct sock *sk, { return 0; } +static inline int selinux_netlbl_socket_connect_locked(struct sock *sk, + struct sockaddr *addr) +{ + return 0; +} #endif /* CONFIG_NETLABEL */ #endif diff --git a/security/selinux/include/netnode.h b/security/selinux/include/netnode.h index df7a5ed6c694..e4dc904c3585 100644 --- a/security/selinux/include/netnode.h +++ b/security/selinux/include/netnode.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Network node table * @@ -7,26 +8,19 @@ * a per-packet basis. * * Author: Paul Moore <paul@paul-moore.com> - * */ /* * (c) Copyright Hewlett-Packard Development Company, L.P., 2007 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * */ #ifndef _SELINUX_NETNODE_H #define _SELINUX_NETNODE_H -int sel_netnode_sid(void *addr, u16 family, u32 *sid); +#include <linux/types.h> + +void sel_netnode_flush(void); + +int sel_netnode_sid(const void *addr, u16 family, u32 *sid); #endif diff --git a/security/selinux/include/netport.h b/security/selinux/include/netport.h index 4d965b83d735..9096a8289948 100644 --- a/security/selinux/include/netport.h +++ b/security/selinux/include/netport.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Network port table * @@ -6,26 +7,19 @@ * needed to reduce the lookup overhead. * * Author: Paul Moore <paul@paul-moore.com> - * */ /* * (c) Copyright Hewlett-Packard Development Company, L.P., 2008 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * */ #ifndef _SELINUX_NETPORT_H #define _SELINUX_NETPORT_H +#include <linux/types.h> + +void sel_netport_flush(void); + int sel_netport_sid(u8 protocol, u16 pnum, u32 *sid); #endif diff --git a/security/selinux/include/objsec.h b/security/selinux/include/objsec.h index aa47bcabb5f6..8fc3de5234ac 100644 --- a/security/selinux/include/objsec.h +++ b/security/selinux/include/objsec.h @@ -1,20 +1,19 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ /* - * NSA Security-Enhanced Linux (SELinux) security module + * Security-Enhanced Linux (SELinux) security module * * This file contains the SELinux security data structures for kernel objects. * - * Author(s): Stephen Smalley, <sds@epoch.ncsc.mil> + * Author(s): Stephen Smalley, <stephen.smalley.work@gmail.com> * Chris Vance, <cvance@nai.com> * Wayne Salamon, <wsalamon@nai.com> * James Morris <jmorris@redhat.com> * * Copyright (C) 2001,2002 Networks Associates Technology, Inc. * Copyright (C) 2003 Red Hat, Inc., James Morris <jmorris@redhat.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2, - * as published by the Free Software Foundation. + * Copyright (C) 2016 Mellanox Technologies */ + #ifndef _SELINUX_OBJSEC_H_ #define _SELINUX_OBJSEC_H_ @@ -24,100 +23,256 @@ #include <linux/binfmts.h> #include <linux/in.h> #include <linux/spinlock.h> +#include <linux/lsm_hooks.h> +#include <linux/msg.h> +#include <net/net_namespace.h> +#include <linux/bpf.h> #include "flask.h" #include "avc.h" +struct avdc_entry { + u32 isid; /* inode SID */ + u32 allowed; /* allowed permission bitmask */ + u32 audited; /* audited permission bitmask */ + bool permissive; /* AVC permissive flag */ +}; + +struct cred_security_struct { + u32 osid; /* SID prior to last execve */ + u32 sid; /* current SID */ + u32 exec_sid; /* exec SID */ + u32 create_sid; /* fscreate SID */ + u32 keycreate_sid; /* keycreate SID */ + u32 sockcreate_sid; /* fscreate SID */ +} __randomize_layout; + struct task_security_struct { - u32 osid; /* SID prior to last execve */ - u32 sid; /* current SID */ - u32 exec_sid; /* exec SID */ - u32 create_sid; /* fscreate SID */ - u32 keycreate_sid; /* keycreate SID */ - u32 sockcreate_sid; /* fscreate SID */ +#define TSEC_AVDC_DIR_SIZE (1 << 2) + struct { + u32 sid; /* current SID for cached entries */ + u32 seqno; /* AVC sequence number */ + unsigned int dir_spot; /* dir cache index to check first */ + struct avdc_entry dir[TSEC_AVDC_DIR_SIZE]; /* dir entries */ + bool permissive_neveraudit; /* permissive and neveraudit */ + } avdcache; +} __randomize_layout; + +static inline bool task_avdcache_permnoaudit(struct task_security_struct *tsec, + u32 sid) +{ + return (tsec->avdcache.permissive_neveraudit && + sid == tsec->avdcache.sid && + tsec->avdcache.seqno == avc_policy_seqno()); +} + +enum label_initialized { + LABEL_INVALID, /* invalid or not initialized */ + LABEL_INITIALIZED, /* initialized */ + LABEL_PENDING }; struct inode_security_struct { - struct inode *inode; /* back pointer to inode object */ - struct list_head list; /* list of inode_security_struct */ - u32 task_sid; /* SID of creating task */ - u32 sid; /* SID of this object */ - u16 sclass; /* security class of this object */ - unsigned char initialized; /* initialization flag */ - struct mutex lock; + struct inode *inode; /* back pointer to inode object */ + struct list_head list; /* list of inode_security_struct */ + u32 task_sid; /* SID of creating task */ + u32 sid; /* SID of this object */ + u16 sclass; /* security class of this object */ + unsigned char initialized; /* initialization flag */ + spinlock_t lock; }; struct file_security_struct { - u32 sid; /* SID of open file description */ - u32 fown_sid; /* SID of file owner (for SIGIO) */ - u32 isid; /* SID of inode at the time of file open */ - u32 pseqno; /* Policy seqno at the time of file open */ + u32 sid; /* SID of open file description */ + u32 fown_sid; /* SID of file owner (for SIGIO) */ + u32 isid; /* SID of inode at the time of file open */ + u32 pseqno; /* Policy seqno at the time of file open */ }; struct superblock_security_struct { - struct super_block *sb; /* back pointer to sb object */ - u32 sid; /* SID of file system superblock */ - u32 def_sid; /* default SID for labeling */ - u32 mntpoint_sid; /* SECURITY_FS_USE_MNTPOINT context for files */ - unsigned int behavior; /* labeling behavior */ - unsigned char flags; /* which mount options were specified */ + u32 sid; /* SID of file system superblock */ + u32 def_sid; /* default SID for labeling */ + u32 mntpoint_sid; /* SECURITY_FS_USE_MNTPOINT context for files */ + unsigned short behavior; /* labeling behavior */ + unsigned short flags; /* which mount options were specified */ struct mutex lock; struct list_head isec_head; spinlock_t isec_lock; }; struct msg_security_struct { - u32 sid; /* SID of message */ + u32 sid; /* SID of message */ }; struct ipc_security_struct { - u16 sclass; /* security class of this object */ - u32 sid; /* SID of IPC resource */ + u16 sclass; /* security class of this object */ + u32 sid; /* SID of IPC resource */ }; struct netif_security_struct { - int ifindex; /* device index */ - u32 sid; /* SID for this interface */ + const struct net *ns; /* network namespace */ + int ifindex; /* device index */ + u32 sid; /* SID for this interface */ }; struct netnode_security_struct { union { - __be32 ipv4; /* IPv4 node address */ - struct in6_addr ipv6; /* IPv6 node address */ + __be32 ipv4; /* IPv4 node address */ + struct in6_addr ipv6; /* IPv6 node address */ } addr; - u32 sid; /* SID for this node */ - u16 family; /* address family */ + u32 sid; /* SID for this node */ + u16 family; /* address family */ }; struct netport_security_struct { - u32 sid; /* SID for this node */ - u16 port; /* port number */ - u8 protocol; /* transport protocol */ + u32 sid; /* SID for this node */ + u16 port; /* port number */ + u8 protocol; /* transport protocol */ }; struct sk_security_struct { #ifdef CONFIG_NETLABEL - enum { /* NetLabel state */ - NLBL_UNSET = 0, - NLBL_REQUIRE, - NLBL_LABELED, - NLBL_REQSKB, - NLBL_CONNLABELED, + enum { /* NetLabel state */ + NLBL_UNSET = 0, + NLBL_REQUIRE, + NLBL_LABELED, + NLBL_REQSKB, + NLBL_CONNLABELED, } nlbl_state; struct netlbl_lsm_secattr *nlbl_secattr; /* NetLabel sec attributes */ #endif - u32 sid; /* SID of this object */ - u32 peer_sid; /* SID of peer */ - u16 sclass; /* sock security class */ + u32 sid; /* SID of this object */ + u32 peer_sid; /* SID of peer */ + u16 sclass; /* sock security class */ + enum { /* SCTP association state */ + SCTP_ASSOC_UNSET = 0, + SCTP_ASSOC_SET, + } sctp_assoc_state; }; struct tun_security_struct { - u32 sid; /* SID for the tun device sockets */ + u32 sid; /* SID for the tun device sockets */ }; struct key_security_struct { - u32 sid; /* SID of key */ + u32 sid; /* SID of key */ }; -extern unsigned int selinux_checkreqprot; +struct ib_security_struct { + u32 sid; /* SID of the queue pair or MAD agent */ +}; + +struct pkey_security_struct { + u64 subnet_prefix; /* Port subnet prefix */ + u16 pkey; /* PKey number */ + u32 sid; /* SID of pkey */ +}; + +struct bpf_security_struct { + u32 sid; /* SID of bpf obj creator */ +}; + +struct perf_event_security_struct { + u32 sid; /* SID of perf_event obj creator */ +}; + +extern struct lsm_blob_sizes selinux_blob_sizes; +static inline struct cred_security_struct *selinux_cred(const struct cred *cred) +{ + return cred->security + selinux_blob_sizes.lbs_cred; +} + +static inline struct task_security_struct * +selinux_task(const struct task_struct *task) +{ + return task->security + selinux_blob_sizes.lbs_task; +} + +static inline struct file_security_struct *selinux_file(const struct file *file) +{ + return file->f_security + selinux_blob_sizes.lbs_file; +} + +static inline struct inode_security_struct * +selinux_inode(const struct inode *inode) +{ + if (unlikely(!inode->i_security)) + return NULL; + return inode->i_security + selinux_blob_sizes.lbs_inode; +} + +static inline struct msg_security_struct * +selinux_msg_msg(const struct msg_msg *msg_msg) +{ + return msg_msg->security + selinux_blob_sizes.lbs_msg_msg; +} + +static inline struct ipc_security_struct * +selinux_ipc(const struct kern_ipc_perm *ipc) +{ + return ipc->security + selinux_blob_sizes.lbs_ipc; +} + +/* + * get the subjective security ID of the current task + */ +static inline u32 current_sid(void) +{ + const struct cred_security_struct *crsec = selinux_cred(current_cred()); + + return crsec->sid; +} + +static inline struct superblock_security_struct * +selinux_superblock(const struct super_block *superblock) +{ + return superblock->s_security + selinux_blob_sizes.lbs_superblock; +} + +#ifdef CONFIG_KEYS +static inline struct key_security_struct *selinux_key(const struct key *key) +{ + return key->security + selinux_blob_sizes.lbs_key; +} +#endif /* CONFIG_KEYS */ + +static inline struct sk_security_struct *selinux_sock(const struct sock *sock) +{ + return sock->sk_security + selinux_blob_sizes.lbs_sock; +} + +static inline struct tun_security_struct *selinux_tun_dev(void *security) +{ + return security + selinux_blob_sizes.lbs_tun_dev; +} + +static inline struct ib_security_struct *selinux_ib(void *ib_sec) +{ + return ib_sec + selinux_blob_sizes.lbs_ib; +} + +static inline struct perf_event_security_struct * +selinux_perf_event(void *perf_event) +{ + return perf_event + selinux_blob_sizes.lbs_perf_event; +} + +#ifdef CONFIG_BPF_SYSCALL +static inline struct bpf_security_struct * +selinux_bpf_map_security(struct bpf_map *map) +{ + return map->security + selinux_blob_sizes.lbs_bpf_map; +} + +static inline struct bpf_security_struct * +selinux_bpf_prog_security(struct bpf_prog *prog) +{ + return prog->aux->security + selinux_blob_sizes.lbs_bpf_prog; +} +static inline struct bpf_security_struct * +selinux_bpf_token_security(struct bpf_token *token) +{ + return token->security + selinux_blob_sizes.lbs_bpf_token; +} +#endif /* CONFIG_BPF_SYSCALL */ #endif /* _SELINUX_OBJSEC_H_ */ diff --git a/security/selinux/include/policycap.h b/security/selinux/include/policycap.h new file mode 100644 index 000000000000..231d02227e59 --- /dev/null +++ b/security/selinux/include/policycap.h @@ -0,0 +1,28 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifndef _SELINUX_POLICYCAP_H_ +#define _SELINUX_POLICYCAP_H_ + +/* Policy capabilities */ +enum { + POLICYDB_CAP_NETPEER, + POLICYDB_CAP_OPENPERM, + POLICYDB_CAP_EXTSOCKCLASS, + POLICYDB_CAP_ALWAYSNETWORK, + POLICYDB_CAP_CGROUPSECLABEL, + POLICYDB_CAP_NNP_NOSUID_TRANSITION, + POLICYDB_CAP_GENFS_SECLABEL_SYMLINKS, + POLICYDB_CAP_IOCTL_SKIP_CLOEXEC, + POLICYDB_CAP_USERSPACE_INITIAL_CONTEXT, + POLICYDB_CAP_NETLINK_XPERM, + POLICYDB_CAP_NETIF_WILDCARD, + POLICYDB_CAP_GENFS_SECLABEL_WILDCARD, + POLICYDB_CAP_FUNCTIONFS_SECLABEL, + POLICYDB_CAP_MEMFD_CLASS, + __POLICYDB_CAP_MAX +}; +#define POLICYDB_CAP_MAX (__POLICYDB_CAP_MAX - 1) + +extern const char *const selinux_policycap_names[__POLICYDB_CAP_MAX]; + +#endif /* _SELINUX_POLICYCAP_H_ */ diff --git a/security/selinux/include/policycap_names.h b/security/selinux/include/policycap_names.h new file mode 100644 index 000000000000..454dab37bda3 --- /dev/null +++ b/security/selinux/include/policycap_names.h @@ -0,0 +1,28 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifndef _SELINUX_POLICYCAP_NAMES_H_ +#define _SELINUX_POLICYCAP_NAMES_H_ + +#include "policycap.h" + +/* clang-format off */ +/* Policy capability names */ +const char *const selinux_policycap_names[__POLICYDB_CAP_MAX] = { + "network_peer_controls", + "open_perms", + "extended_socket_class", + "always_check_network", + "cgroup_seclabel", + "nnp_nosuid_transition", + "genfs_seclabel_symlinks", + "ioctl_skip_cloexec", + "userspace_initial_context", + "netlink_xperm", + "netif_wildcard", + "genfs_seclabel_wildcard", + "functionfs_seclabel", + "memfd_class", +}; +/* clang-format on */ + +#endif /* _SELINUX_POLICYCAP_NAMES_H_ */ diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h index 8fd8e18ea340..5d1dad8058b1 100644 --- a/security/selinux/include/security.h +++ b/security/selinux/include/security.h @@ -1,96 +1,233 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Security server interface. * - * Author : Stephen Smalley, <sds@epoch.ncsc.mil> + * Author : Stephen Smalley, <stephen.smalley.work@gmail.com> * */ #ifndef _SELINUX_SECURITY_H_ #define _SELINUX_SECURITY_H_ +#include <linux/compiler.h> #include <linux/dcache.h> #include <linux/magic.h> #include <linux/types.h> +#include <linux/rcupdate.h> +#include <linux/refcount.h> +#include <linux/workqueue.h> +#include <linux/delay.h> +#include <linux/printk.h> #include "flask.h" +#include "policycap.h" -#define SECSID_NULL 0x00000000 /* unspecified SID */ -#define SECSID_WILD 0xffffffff /* wildcard SID */ -#define SECCLASS_NULL 0x0000 /* no class */ +#define SECSID_NULL 0x00000000 /* unspecified SID */ +#define SECSID_WILD 0xffffffff /* wildcard SID */ +#define SECCLASS_NULL 0x0000 /* no class */ /* Identify specific policy version changes */ -#define POLICYDB_VERSION_BASE 15 -#define POLICYDB_VERSION_BOOL 16 -#define POLICYDB_VERSION_IPV6 17 -#define POLICYDB_VERSION_NLCLASS 18 -#define POLICYDB_VERSION_VALIDATETRANS 19 -#define POLICYDB_VERSION_MLS 19 -#define POLICYDB_VERSION_AVTAB 20 -#define POLICYDB_VERSION_RANGETRANS 21 -#define POLICYDB_VERSION_POLCAP 22 -#define POLICYDB_VERSION_PERMISSIVE 23 -#define POLICYDB_VERSION_BOUNDARY 24 -#define POLICYDB_VERSION_FILENAME_TRANS 25 -#define POLICYDB_VERSION_ROLETRANS 26 -#define POLICYDB_VERSION_NEW_OBJECT_DEFAULTS 27 -#define POLICYDB_VERSION_DEFAULT_TYPE 28 +#define POLICYDB_VERSION_BASE 15 +#define POLICYDB_VERSION_BOOL 16 +#define POLICYDB_VERSION_IPV6 17 +#define POLICYDB_VERSION_NLCLASS 18 +#define POLICYDB_VERSION_VALIDATETRANS 19 +#define POLICYDB_VERSION_MLS 19 +#define POLICYDB_VERSION_AVTAB 20 +#define POLICYDB_VERSION_RANGETRANS 21 +#define POLICYDB_VERSION_POLCAP 22 +#define POLICYDB_VERSION_PERMISSIVE 23 +#define POLICYDB_VERSION_BOUNDARY 24 +#define POLICYDB_VERSION_FILENAME_TRANS 25 +#define POLICYDB_VERSION_ROLETRANS 26 +#define POLICYDB_VERSION_NEW_OBJECT_DEFAULTS 27 +#define POLICYDB_VERSION_DEFAULT_TYPE 28 +#define POLICYDB_VERSION_CONSTRAINT_NAMES 29 +#define POLICYDB_VERSION_XPERMS_IOCTL 30 +#define POLICYDB_VERSION_INFINIBAND 31 +#define POLICYDB_VERSION_GLBLUB 32 +#define POLICYDB_VERSION_COMP_FTRANS 33 /* compressed filename transitions */ +#define POLICYDB_VERSION_COND_XPERMS 34 /* extended permissions in conditional policies */ +#define POLICYDB_VERSION_NEVERAUDIT 35 /* neveraudit types */ /* Range of policy versions we understand*/ -#define POLICYDB_VERSION_MIN POLICYDB_VERSION_BASE -#ifdef CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX -#define POLICYDB_VERSION_MAX CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX_VALUE -#else -#define POLICYDB_VERSION_MAX POLICYDB_VERSION_DEFAULT_TYPE -#endif +#define POLICYDB_VERSION_MIN POLICYDB_VERSION_BASE +#define POLICYDB_VERSION_MAX POLICYDB_VERSION_NEVERAUDIT /* Mask for just the mount related flags */ -#define SE_MNTMASK 0x0f +#define SE_MNTMASK 0x0f /* Super block security struct flags for mount options */ +/* BE CAREFUL, these need to be the low order bits for selinux_get_mnt_opts */ #define CONTEXT_MNT 0x01 #define FSCONTEXT_MNT 0x02 -#define ROOTCONTEXT_MNT 0x04 +#define ROOTCONTEXT_MNT 0x04 #define DEFCONTEXT_MNT 0x08 +#define SBLABEL_MNT 0x10 /* Non-mount related flags */ -#define SE_SBINITIALIZED 0x10 -#define SE_SBPROC 0x20 -#define SE_SBLABELSUPP 0x40 - -#define CONTEXT_STR "context=" -#define FSCONTEXT_STR "fscontext=" -#define ROOTCONTEXT_STR "rootcontext=" -#define DEFCONTEXT_STR "defcontext=" -#define LABELSUPP_STR "seclabel" +#define SE_SBINITIALIZED 0x0100 +#define SE_SBPROC 0x0200 +#define SE_SBGENFS 0x0400 +#define SE_SBGENFS_XATTR 0x0800 +#define SE_SBNATIVE 0x1000 + +#define CONTEXT_STR "context" +#define FSCONTEXT_STR "fscontext" +#define ROOTCONTEXT_STR "rootcontext" +#define DEFCONTEXT_STR "defcontext" +#define SECLABEL_STR "seclabel" struct netlbl_lsm_secattr; -extern int selinux_enabled; - -/* Policy capabilities */ -enum { - POLICYDB_CAPABILITY_NETPEER, - POLICYDB_CAPABILITY_OPENPERM, - __POLICYDB_CAPABILITY_MAX -}; -#define POLICYDB_CAPABILITY_MAX (__POLICYDB_CAPABILITY_MAX - 1) - -extern int selinux_policycap_netpeer; -extern int selinux_policycap_openperm; +extern int selinux_enabled_boot; /* * type_datum properties * available at the kernel policy version >= POLICYDB_VERSION_BOUNDARY */ -#define TYPEDATUM_PROPERTY_PRIMARY 0x0001 -#define TYPEDATUM_PROPERTY_ATTRIBUTE 0x0002 +#define TYPEDATUM_PROPERTY_PRIMARY 0x0001 +#define TYPEDATUM_PROPERTY_ATTRIBUTE 0x0002 /* limitation of boundary depth */ -#define POLICYDB_BOUNDS_MAXDEPTH 4 +#define POLICYDB_BOUNDS_MAXDEPTH 4 -int security_mls_enabled(void); +struct selinux_policy; -int security_load_policy(void *data, size_t len); -int security_read_policy(void **data, size_t *len); -size_t security_policydb_len(void); +struct selinux_state { +#ifdef CONFIG_SECURITY_SELINUX_DEVELOP + bool enforcing; +#endif + bool initialized; + bool policycap[__POLICYDB_CAP_MAX]; + + struct page *status_page; + struct mutex status_lock; + + struct selinux_policy __rcu *policy; + struct mutex policy_mutex; +} __randomize_layout; + +void selinux_avc_init(void); + +extern struct selinux_state selinux_state; + +static inline bool selinux_initialized(void) +{ + /* do a synchronized load to avoid race conditions */ + return smp_load_acquire(&selinux_state.initialized); +} + +static inline void selinux_mark_initialized(void) +{ + /* do a synchronized write to avoid race conditions */ + smp_store_release(&selinux_state.initialized, true); +} + +#ifdef CONFIG_SECURITY_SELINUX_DEVELOP +static inline bool enforcing_enabled(void) +{ + return READ_ONCE(selinux_state.enforcing); +} + +static inline void enforcing_set(bool value) +{ + WRITE_ONCE(selinux_state.enforcing, value); +} +#else +static inline bool enforcing_enabled(void) +{ + return true; +} + +static inline void enforcing_set(bool value) +{ +} +#endif + +static inline bool checkreqprot_get(void) +{ + /* non-zero/true checkreqprot values are no longer supported */ + return 0; +} + +static inline bool selinux_policycap_netpeer(void) +{ + return READ_ONCE(selinux_state.policycap[POLICYDB_CAP_NETPEER]); +} + +static inline bool selinux_policycap_openperm(void) +{ + return READ_ONCE(selinux_state.policycap[POLICYDB_CAP_OPENPERM]); +} + +static inline bool selinux_policycap_extsockclass(void) +{ + return READ_ONCE(selinux_state.policycap[POLICYDB_CAP_EXTSOCKCLASS]); +} + +static inline bool selinux_policycap_alwaysnetwork(void) +{ + return READ_ONCE(selinux_state.policycap[POLICYDB_CAP_ALWAYSNETWORK]); +} + +static inline bool selinux_policycap_cgroupseclabel(void) +{ + return READ_ONCE(selinux_state.policycap[POLICYDB_CAP_CGROUPSECLABEL]); +} + +static inline bool selinux_policycap_nnp_nosuid_transition(void) +{ + return READ_ONCE( + selinux_state.policycap[POLICYDB_CAP_NNP_NOSUID_TRANSITION]); +} + +static inline bool selinux_policycap_genfs_seclabel_symlinks(void) +{ + return READ_ONCE( + selinux_state.policycap[POLICYDB_CAP_GENFS_SECLABEL_SYMLINKS]); +} + +static inline bool selinux_policycap_ioctl_skip_cloexec(void) +{ + return READ_ONCE( + selinux_state.policycap[POLICYDB_CAP_IOCTL_SKIP_CLOEXEC]); +} + +static inline bool selinux_policycap_userspace_initial_context(void) +{ + return READ_ONCE( + selinux_state.policycap[POLICYDB_CAP_USERSPACE_INITIAL_CONTEXT]); +} + +static inline bool selinux_policycap_netlink_xperm(void) +{ + return READ_ONCE( + selinux_state.policycap[POLICYDB_CAP_NETLINK_XPERM]); +} + +static inline bool selinux_policycap_functionfs_seclabel(void) +{ + return READ_ONCE( + selinux_state.policycap[POLICYDB_CAP_FUNCTIONFS_SECLABEL]); +} + +static inline bool selinux_policycap_memfd_class(void) +{ + return READ_ONCE(selinux_state.policycap[POLICYDB_CAP_MEMFD_CLASS]); +} + +struct selinux_policy_convert_data; +struct selinux_load_state { + struct selinux_policy *policy; + struct selinux_policy_convert_data *convert_data; +}; + +int security_mls_enabled(void); +int security_load_policy(void *data, size_t len, + struct selinux_load_state *load_state); +void selinux_policy_commit(struct selinux_load_state *load_state); +void selinux_policy_cancel(struct selinux_load_state *load_state); +int security_read_policy(void **data, size_t *len); +int security_read_state_kernel(void **data, size_t *len); int security_policycap_supported(unsigned int req_cap); #define SEL_VEC_MAX 32 @@ -102,14 +239,45 @@ struct av_decision { u32 flags; }; +#define XPERMS_ALLOWED 1 +#define XPERMS_AUDITALLOW 2 +#define XPERMS_DONTAUDIT 4 + +#define security_xperm_set(perms, x) ((perms)[(x) >> 5] |= 1 << ((x)&0x1f)) +#define security_xperm_test(perms, x) (1 & ((perms)[(x) >> 5] >> ((x)&0x1f))) +struct extended_perms_data { + u32 p[8]; +}; + +struct extended_perms_decision { + u8 used; + u8 driver; + u8 base_perm; + struct extended_perms_data *allowed; + struct extended_perms_data *auditallow; + struct extended_perms_data *dontaudit; +}; + +struct extended_perms { + u16 len; /* length associated decision chain */ + u8 base_perms; /* which base permissions are covered */ + struct extended_perms_data drivers; /* flag drivers that are used */ +}; + /* definitions of av_decision.flags */ -#define AVD_FLAGS_PERMISSIVE 0x0001 +#define AVD_FLAGS_PERMISSIVE 0x0001 +#define AVD_FLAGS_NEVERAUDIT 0x0002 + +void security_compute_av(u32 ssid, u32 tsid, u16 tclass, + struct av_decision *avd, + struct extended_perms *xperms); -void security_compute_av(u32 ssid, u32 tsid, - u16 tclass, struct av_decision *avd); +void security_compute_xperms_decision(u32 ssid, u32 tsid, u16 tclass, u8 driver, + u8 base_perm, + struct extended_perms_decision *xpermd); -void security_compute_av_user(u32 ssid, u32 tsid, - u16 tclass, struct av_decision *avd); +void security_compute_av_user(u32 ssid, u32 tsid, u16 tclass, + struct av_decision *avd); int security_transition_sid(u32 ssid, u32 tsid, u16 tclass, const struct qstr *qstr, u32 *out_sid); @@ -117,19 +285,20 @@ int security_transition_sid(u32 ssid, u32 tsid, u16 tclass, int security_transition_sid_user(u32 ssid, u32 tsid, u16 tclass, const char *objname, u32 *out_sid); -int security_member_sid(u32 ssid, u32 tsid, - u16 tclass, u32 *out_sid); +int security_member_sid(u32 ssid, u32 tsid, u16 tclass, u32 *out_sid); -int security_change_sid(u32 ssid, u32 tsid, - u16 tclass, u32 *out_sid); +int security_change_sid(u32 ssid, u32 tsid, u16 tclass, u32 *out_sid); -int security_sid_to_context(u32 sid, char **scontext, - u32 *scontext_len); +int security_sid_to_context(u32 sid, char **scontext, u32 *scontext_len); int security_sid_to_context_force(u32 sid, char **scontext, u32 *scontext_len); +int security_sid_to_context_inval(u32 sid, char **scontext, u32 *scontext_len); + int security_context_to_sid(const char *scontext, u32 scontext_len, - u32 *out_sid); + u32 *out_sid, gfp_t gfp); + +int security_context_str_to_sid(const char *scontext, u32 *out_sid, gfp_t gfp); int security_context_to_sid_default(const char *scontext, u32 scontext_len, u32 *out_sid, u32 def_sid, gfp_t gfp_flags); @@ -137,63 +306,69 @@ int security_context_to_sid_default(const char *scontext, u32 scontext_len, int security_context_to_sid_force(const char *scontext, u32 scontext_len, u32 *sid); -int security_get_user_sids(u32 callsid, char *username, - u32 **sids, u32 *nel); +int security_get_user_sids(u32 fromsid, const char *username, u32 **sids, u32 *nel); int security_port_sid(u8 protocol, u16 port, u32 *out_sid); -int security_netif_sid(char *name, u32 *if_sid); +int security_ib_pkey_sid(u64 subnet_prefix, u16 pkey_num, u32 *out_sid); + +int security_ib_endport_sid(const char *dev_name, u8 port_num, u32 *out_sid); -int security_node_sid(u16 domain, void *addr, u32 addrlen, - u32 *out_sid); +int security_netif_sid(const char *name, u32 *if_sid); + +int security_node_sid(u16 domain, const void *addr, u32 addrlen, u32 *out_sid); int security_validate_transition(u32 oldsid, u32 newsid, u32 tasksid, u16 tclass); -int security_bounded_transition(u32 oldsid, u32 newsid); +int security_validate_transition_user(u32 oldsid, u32 newsid, u32 tasksid, + u16 tclass); + +int security_bounded_transition(u32 old_sid, u32 new_sid); int security_sid_mls_copy(u32 sid, u32 mls_sid, u32 *new_sid); -int security_net_peersid_resolve(u32 nlbl_sid, u32 nlbl_type, - u32 xfrm_sid, +int security_net_peersid_resolve(u32 nlbl_sid, u32 nlbl_type, u32 xfrm_sid, u32 *peer_sid); -int security_get_classes(char ***classes, int *nclasses); -int security_get_permissions(char *class, char ***perms, int *nperms); +int security_get_classes(struct selinux_policy *policy, char ***classes, + u32 *nclasses); +int security_get_permissions(struct selinux_policy *policy, const char *class, + char ***perms, u32 *nperms); int security_get_reject_unknown(void); int security_get_allow_unknown(void); -#define SECURITY_FS_USE_XATTR 1 /* use xattr */ -#define SECURITY_FS_USE_TRANS 2 /* use transition SIDs, e.g. devpts/tmpfs */ -#define SECURITY_FS_USE_TASK 3 /* use task SIDs, e.g. pipefs/sockfs */ -#define SECURITY_FS_USE_GENFS 4 /* use the genfs support */ -#define SECURITY_FS_USE_NONE 5 /* no labeling support */ -#define SECURITY_FS_USE_MNTPOINT 6 /* use mountpoint labeling */ -#define SECURITY_FS_USE_NATIVE 7 /* use native label support */ -#define SECURITY_FS_USE_MAX 7 /* Highest SECURITY_FS_USE_XXX */ +#define SECURITY_FS_USE_XATTR 1 /* use xattr */ +#define SECURITY_FS_USE_TRANS 2 /* use transition SIDs, e.g. devpts/tmpfs */ +#define SECURITY_FS_USE_TASK 3 /* use task SIDs, e.g. pipefs/sockfs */ +#define SECURITY_FS_USE_GENFS 4 /* use the genfs support */ +#define SECURITY_FS_USE_NONE 5 /* no labeling support */ +#define SECURITY_FS_USE_MNTPOINT 6 /* use mountpoint labeling */ +#define SECURITY_FS_USE_NATIVE 7 /* use native label support */ +#define SECURITY_FS_USE_MAX 7 /* Highest SECURITY_FS_USE_XXX */ + +int security_fs_use(struct super_block *sb); -int security_fs_use(const char *fstype, unsigned int *behavior, - u32 *sid); +int security_genfs_sid(const char *fstype, const char *path, u16 sclass, + u32 *sid); -int security_genfs_sid(const char *fstype, char *name, u16 sclass, - u32 *sid); +int selinux_policy_genfs_sid(struct selinux_policy *policy, const char *fstype, + const char *path, u16 sclass, u32 *sid); #ifdef CONFIG_NETLABEL int security_netlbl_secattr_to_sid(struct netlbl_lsm_secattr *secattr, u32 *sid); -int security_netlbl_sid_to_secattr(u32 sid, - struct netlbl_lsm_secattr *secattr); +int security_netlbl_sid_to_secattr(u32 sid, struct netlbl_lsm_secattr *secattr); #else -static inline int security_netlbl_secattr_to_sid( - struct netlbl_lsm_secattr *secattr, - u32 *sid) +static inline int +security_netlbl_secattr_to_sid(struct netlbl_lsm_secattr *secattr, u32 *sid) { return -EIDRM; } -static inline int security_netlbl_sid_to_secattr(u32 sid, - struct netlbl_lsm_secattr *secattr) +static inline int +security_netlbl_sid_to_secattr(u32 sid, struct netlbl_lsm_secattr *secattr) { return -ENOENT; } @@ -206,28 +381,29 @@ const char *security_get_initial_sid_context(u32 sid); */ extern struct page *selinux_kernel_status_page(void); -#define SELINUX_KERNEL_STATUS_VERSION 1 +#define SELINUX_KERNEL_STATUS_VERSION 1 struct selinux_kernel_status { - u32 version; /* version number of thie structure */ - u32 sequence; /* sequence number of seqlock logic */ - u32 enforcing; /* current setting of enforcing mode */ - u32 policyload; /* times of policy reloaded */ - u32 deny_unknown; /* current setting of deny_unknown */ + u32 version; /* version number of the structure */ + u32 sequence; /* sequence number of seqlock logic */ + u32 enforcing; /* current setting of enforcing mode */ + u32 policyload; /* times of policy reloaded */ + u32 deny_unknown; /* current setting of deny_unknown */ /* * The version > 0 supports above members. */ -} __attribute__((packed)); +} __packed; -extern void selinux_status_update_setenforce(int enforcing); -extern void selinux_status_update_policyload(int seqno); +extern void selinux_status_update_setenforce(bool enforcing); +extern void selinux_status_update_policyload(u32 seqno); extern void selinux_complete_init(void); -extern int selinux_disable(void); -extern void exit_sel_fs(void); extern struct path selinux_null; -extern struct vfsmount *selinuxfs_mount; extern void selnl_notify_setenforce(int val); extern void selnl_notify_policyload(u32 seqno); extern int selinux_nlmsg_lookup(u16 sclass, u16 nlmsg_type, u32 *perm); -#endif /* _SELINUX_SECURITY_H_ */ +extern void avtab_cache_init(void); +extern void ebitmap_cache_init(void); +extern void hashtab_cache_init(void); +extern int security_sidtab_hash_stats(char *page); +#endif /* _SELINUX_SECURITY_H_ */ diff --git a/security/selinux/include/xfrm.h b/security/selinux/include/xfrm.h index 65f67cb0aefb..de485556ae29 100644 --- a/security/selinux/include/xfrm.h +++ b/security/selinux/include/xfrm.h @@ -1,38 +1,34 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * SELinux support for the XFRM LSM hooks * * Author : Trent Jaeger, <jaegert@us.ibm.com> * Updated : Venkat Yekkirala, <vyekkirala@TrustedCS.com> */ + #ifndef _SELINUX_XFRM_H_ #define _SELINUX_XFRM_H_ +#include <linux/lsm_audit.h> #include <net/flow.h> +#include <net/xfrm.h> int selinux_xfrm_policy_alloc(struct xfrm_sec_ctx **ctxp, - struct xfrm_user_sec_ctx *sec_ctx); + struct xfrm_user_sec_ctx *uctx, gfp_t gfp); int selinux_xfrm_policy_clone(struct xfrm_sec_ctx *old_ctx, struct xfrm_sec_ctx **new_ctxp); void selinux_xfrm_policy_free(struct xfrm_sec_ctx *ctx); int selinux_xfrm_policy_delete(struct xfrm_sec_ctx *ctx); int selinux_xfrm_state_alloc(struct xfrm_state *x, - struct xfrm_user_sec_ctx *sec_ctx, u32 secid); + struct xfrm_user_sec_ctx *uctx); +int selinux_xfrm_state_alloc_acquire(struct xfrm_state *x, + struct xfrm_sec_ctx *polsec, u32 secid); void selinux_xfrm_state_free(struct xfrm_state *x); int selinux_xfrm_state_delete(struct xfrm_state *x); -int selinux_xfrm_policy_lookup(struct xfrm_sec_ctx *ctx, u32 fl_secid, u8 dir); +int selinux_xfrm_policy_lookup(struct xfrm_sec_ctx *ctx, u32 fl_secid); int selinux_xfrm_state_pol_flow_match(struct xfrm_state *x, - struct xfrm_policy *xp, const struct flowi *fl); - -/* - * Extract the security blob from the sock (it's actually on the socket) - */ -static inline struct inode_security_struct *get_sock_isec(struct sock *sk) -{ - if (!sk->sk_socket) - return NULL; - - return SOCK_INODE(sk->sk_socket)->i_security; -} + struct xfrm_policy *xp, + const struct flowi_common *flic); #ifdef CONFIG_SECURITY_NETWORK_XFRM extern atomic_t selinux_xfrm_refcount; @@ -42,16 +38,21 @@ static inline int selinux_xfrm_enabled(void) return (atomic_read(&selinux_xfrm_refcount) > 0); } -int selinux_xfrm_sock_rcv_skb(u32 sid, struct sk_buff *skb, - struct common_audit_data *ad); -int selinux_xfrm_postroute_last(u32 isec_sid, struct sk_buff *skb, - struct common_audit_data *ad, u8 proto); +int selinux_xfrm_sock_rcv_skb(u32 sk_sid, struct sk_buff *skb, + struct common_audit_data *ad); +int selinux_xfrm_postroute_last(u32 sk_sid, struct sk_buff *skb, + struct common_audit_data *ad, u8 proto); int selinux_xfrm_decode_session(struct sk_buff *skb, u32 *sid, int ckall); +int selinux_xfrm_skb_sid(struct sk_buff *skb, u32 *sid); static inline void selinux_xfrm_notify_policyload(void) { - atomic_inc(&flow_cache_genid); - rt_genid_bump(&init_net); + struct net *net; + + down_read(&net_rwsem); + for_each_net(net) + rt_genid_bump_all(net); + up_read(&net_rwsem); } #else static inline int selinux_xfrm_enabled(void) @@ -59,19 +60,21 @@ static inline int selinux_xfrm_enabled(void) return 0; } -static inline int selinux_xfrm_sock_rcv_skb(u32 isec_sid, struct sk_buff *skb, - struct common_audit_data *ad) +static inline int selinux_xfrm_sock_rcv_skb(u32 sk_sid, struct sk_buff *skb, + struct common_audit_data *ad) { return 0; } -static inline int selinux_xfrm_postroute_last(u32 isec_sid, struct sk_buff *skb, - struct common_audit_data *ad, u8 proto) +static inline int selinux_xfrm_postroute_last(u32 sk_sid, struct sk_buff *skb, + struct common_audit_data *ad, + u8 proto) { return 0; } -static inline int selinux_xfrm_decode_session(struct sk_buff *skb, u32 *sid, int ckall) +static inline int selinux_xfrm_decode_session(struct sk_buff *skb, u32 *sid, + int ckall) { *sid = SECSID_NULL; return 0; @@ -80,12 +83,12 @@ static inline int selinux_xfrm_decode_session(struct sk_buff *skb, u32 *sid, int static inline void selinux_xfrm_notify_policyload(void) { } -#endif -static inline void selinux_skb_xfrm_sid(struct sk_buff *skb, u32 *sid) +static inline int selinux_xfrm_skb_sid(struct sk_buff *skb, u32 *sid) { - int err = selinux_xfrm_decode_session(skb, sid, 0); - BUG_ON(err); + *sid = SECSID_NULL; + return 0; } +#endif #endif /* _SELINUX_XFRM_H_ */ |
