aboutsummaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
Diffstat (limited to 'security')
-rw-r--r--security/selinux/hooks.c36
-rw-r--r--security/selinux/include/audit.h1
-rw-r--r--security/selinux/include/avc.h41
-rw-r--r--security/selinux/include/avc_ss.h2
-rw-r--r--security/selinux/include/classmap.h342
-rw-r--r--security/selinux/include/conditional.h4
-rw-r--r--security/selinux/include/ima.h2
-rw-r--r--security/selinux/include/initial_sid_to_string.h57
-rw-r--r--security/selinux/include/netif.h4
-rw-r--r--security/selinux/include/netlabel.h53
-rw-r--r--security/selinux/include/objsec.h129
-rw-r--r--security/selinux/include/policycap.h2
-rw-r--r--security/selinux/include/policycap_names.h4
-rw-r--r--security/selinux/include/security.h161
-rw-r--r--security/selinux/include/xfrm.h4
-rw-r--r--security/selinux/selinuxfs.c144
-rw-r--r--security/selinux/ss/avtab.c101
-rw-r--r--security/selinux/ss/policydb.c38
-rw-r--r--security/selinux/ss/services.c13
19 files changed, 538 insertions, 600 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 340b2bbbb2dd3..c96836da38022 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -2313,6 +2313,19 @@ static int selinux_bprm_creds_for_exec(struct linux_binprm *bprm)
new_tsec->keycreate_sid = 0;
new_tsec->sockcreate_sid = 0;
+ /*
+ * Before policy is loaded, label any task outside kernel space
+ * as SECINITSID_INIT, so that any userspace tasks surviving from
+ * early boot end up with a label different from SECINITSID_KERNEL
+ * (if the policy chooses to set SECINITSID_INIT != SECINITSID_KERNEL).
+ */
+ if (!selinux_initialized()) {
+ new_tsec->sid = SECINITSID_INIT;
+ /* also clear the exec_sid just in case */
+ new_tsec->exec_sid = 0;
+ return 0;
+ }
+
if (old_tsec->exec_sid) {
new_tsec->sid = old_tsec->exec_sid;
/* Reset exec SID on execve. */
@@ -4547,6 +4560,21 @@ static int sock_has_perm(struct sock *sk, u32 perms)
if (sksec->sid == SECINITSID_KERNEL)
return 0;
+ /*
+ * Before POLICYDB_CAP_USERSPACE_INITIAL_CONTEXT, sockets that
+ * inherited the kernel context from early boot used to be skipped
+ * here, so preserve that behavior unless the capability is set.
+ *
+ * By setting the capability the policy signals that it is ready
+ * for this quirk to be fixed. Note that sockets created by a kernel
+ * thread or a usermode helper executed without a transition will
+ * still be skipped in this check regardless of the policycap
+ * setting.
+ */
+ if (!selinux_policycap_userspace_initial_context() &&
+ sksec->sid == SECINITSID_INIT)
+ return 0;
+
ad_net_init_from_sk(&ad, &net, sk);
return avc_has_perm(current_sid(), sksec->sid, sksec->sclass, perms,
@@ -4661,6 +4689,13 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in
return -EINVAL;
addr4 = (struct sockaddr_in *)address;
if (family_sa == AF_UNSPEC) {
+ if (family == PF_INET6) {
+ /* Length check from inet6_bind_sk() */
+ if (addrlen < SIN6_LEN_RFC2133)
+ return -EINVAL;
+ /* Family check from __inet6_bind() */
+ goto err_af;
+ }
/* see __inet_bind(), we only want to allow
* AF_UNSPEC if the address is INADDR_ANY
*/
@@ -6425,7 +6460,6 @@ static int selinux_setprocattr(const char *name, void *value, size_t size)
if (sid == 0)
goto abort_change;
- /* Only allow single threaded processes to change context */
if (!current_is_single_threaded()) {
error = security_bounded_transition(tsec->sid, sid);
if (error)
diff --git a/security/selinux/include/audit.h b/security/selinux/include/audit.h
index d5495134a5b9e..52aca71210b47 100644
--- a/security/selinux/include/audit.h
+++ b/security/selinux/include/audit.h
@@ -57,4 +57,3 @@ int selinux_audit_rule_match(u32 sid, u32 field, u32 op, void *rule);
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 8f0aa66ccb13b..96a614d47df8d 100644
--- a/security/selinux/include/avc.h
+++ b/security/selinux/include/avc.h
@@ -4,6 +4,7 @@
*
* Author : Stephen Smalley, <stephen.smalley.work@gmail.com>
*/
+
#ifndef _SELINUX_AVC_H_
#define _SELINUX_AVC_H_
@@ -60,11 +61,8 @@ 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;
denied = requested & ~avd->allowed;
@@ -96,9 +94,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, int result,
- struct common_audit_data *a);
+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.
@@ -119,36 +116,29 @@ 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,
+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, result,
- a);
+ return slow_avc_audit(ssid, tsid, tclass, requested, audited, denied,
+ result, a);
}
-#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 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(u32 ssid, u32 tsid,
- u16 tclass, u32 requested,
+int avc_has_perm(u32 ssid, u32 tsid, u16 tclass, u32 requested,
struct common_audit_data *auditdata);
int avc_has_extended_perms(u32 ssid, u32 tsid, u16 tclass, u32 requested,
u8 driver, u8 perm, struct common_audit_data *ad);
-
u32 avc_policy_seqno(void);
#define AVC_CALLBACK_GRANT 1
@@ -156,7 +146,7 @@ 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
@@ -173,4 +163,3 @@ 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 88b139e086c4f..48ad64d540328 100644
--- a/security/selinux/include/avc_ss.h
+++ b/security/selinux/include/avc_ss.h
@@ -4,6 +4,7 @@
*
* Author : Stephen Smalley, <stephen.smalley.work@gmail.com>
*/
+
#ifndef _SELINUX_AVC_SS_H_
#define _SELINUX_AVC_SS_H_
@@ -20,4 +21,3 @@ struct security_class_mapping {
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 a3c380775d410..7229c9bf6c270 100644
--- a/security/selinux/include/classmap.h
+++ b/security/selinux/include/classmap.h
@@ -1,34 +1,40 @@
/* SPDX-License-Identifier: GPL-2.0 */
+
#include <linux/capability.h>
#include <linux/socket.h>
-#define COMMON_FILE_SOCK_PERMS "ioctl", "read", "write", "create", \
- "getattr", "setattr", "lock", "relabelfrom", "relabelto", "append", "map"
+#define COMMON_FILE_SOCK_PERMS \
+ "ioctl", "read", "write", "create", "getattr", "setattr", "lock", \
+ "relabelfrom", "relabelto", "append", "map"
-#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"
+#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"
-#define COMMON_SOCK_PERMS COMMON_FILE_SOCK_PERMS, "bind", "connect", \
- "listen", "accept", "getopt", "setopt", "shutdown", "recvfrom", \
- "sendto", "name_bind"
+#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_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_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"
+#define COMMON_CAP2_PERMS \
+ "mac_override", "mac_admin", "syslog", "wake_alarm", "block_suspend", \
+ "audit_read", "perfmon", "bpf", "checkpoint_restore"
#if CAP_LAST_CAP > CAP_CHECKPOINT_RESTORE
#error New capability defined, please update COMMON_CAP2_PERMS.
@@ -40,224 +46,140 @@
*/
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", "validate_trans", 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", "getrlimit", NULL } },
- { "process2",
- { "nnp_transition", "nosuid_transition", 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", "module_load", NULL } },
- { "capability",
- { COMMON_CAP_PERMS, NULL } },
+ { "ipc_info", "syslog_read", "syslog_mod", "syslog_console",
+ "module_request", "module_load", NULL } },
+ { "capability", { COMMON_CAP_PERMS, NULL } },
{ "filesystem",
- { "mount", "remount", "unmount", "getattr",
- "relabelfrom", "relabelto", "associate", "quotamod",
- "quotaget", "watch", 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,
- "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 } },
+ { 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 } },
+ { COMMON_SOCK_PERMS, "nlmsg_read", "nlmsg_write", 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", 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 } },
- { "netlink_iscsi_socket",
- { COMMON_SOCK_PERMS, NULL } },
+ { COMMON_SOCK_PERMS, "nlmsg_read", "nlmsg_write", 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_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 } },
+ { COMMON_SOCK_PERMS, "nlmsg_read", "nlmsg_write", "nlmsg_relay",
+ "nlmsg_readpriv", "nlmsg_tty_audit", 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 } },
- { "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 } },
+ { "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 } },
+ { COMMON_SOCK_PERMS, "node_bind", "name_connect", NULL } },
{ "memprotect", { "mmap_zero", NULL } },
{ "peer", { "recv", NULL } },
- { "capability2",
- { COMMON_CAP2_PERMS, NULL } },
+ { "capability2", { COMMON_CAP2_PERMS, NULL } },
{ "kernel_service", { "use_as_override", "create_files_as", 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 } },
+ { "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 } },
+ { 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 } },
+ { "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", NULL } },
- { "user_namespace",
- { "create", NULL } },
+ { "anon_inode", { COMMON_FILE_PERMS, NULL } },
+ { "io_uring", { "override_creds", "sqpoll", "cmd", NULL } },
+ { "user_namespace", { "create", NULL } },
{ NULL }
- };
+};
#if PF_MAX > 46
#error New address family defined, please update secclass_map.
diff --git a/security/selinux/include/conditional.h b/security/selinux/include/conditional.h
index 693a654714eb5..5910bb7c2ecad 100644
--- a/security/selinux/include/conditional.h
+++ b/security/selinux/include/conditional.h
@@ -13,8 +13,8 @@
#include "security.h"
-int security_get_bools(struct selinux_policy *policy,
- u32 *len, char ***names, int **values);
+int security_get_bools(struct selinux_policy *policy, u32 *len, char ***names,
+ int **values);
int security_set_bools(u32 len, int *values);
diff --git a/security/selinux/include/ima.h b/security/selinux/include/ima.h
index 93c05e97eb7ff..38ab302f59463 100644
--- a/security/selinux/include/ima.h
+++ b/security/selinux/include/ima.h
@@ -25,4 +25,4 @@ static inline void selinux_ima_measure_state_locked(void)
}
#endif
-#endif /* _SELINUX_IMA_H_ */
+#endif /* _SELINUX_IMA_H_ */
diff --git a/security/selinux/include/initial_sid_to_string.h b/security/selinux/include/initial_sid_to_string.h
index ecc6e74fa09bd..99b353b2abb41 100644
--- a/security/selinux/include/initial_sid_to_string.h
+++ b/security/selinux/include/initial_sid_to_string.h
@@ -3,33 +3,32 @@
#include <linux/stddef.h>
static const char *const initial_sid_to_string[] = {
- NULL,
- "kernel",
- "security",
- "unlabeled",
- NULL,
- "file",
- NULL,
- NULL,
- "any_socket",
- "port",
- "netif",
- "netmsg",
- "node",
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- "devnull",
+ 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 85ec30d11144b..2838bdc170dd6 100644
--- a/security/selinux/include/netif.h
+++ b/security/selinux/include/netif.h
@@ -11,6 +11,7 @@
* Copyright (C) 2007 Hewlett-Packard Development Company, L.P.
* Paul Moore <paul@paul-moore.com>
*/
+
#ifndef _SELINUX_NETIF_H_
#define _SELINUX_NETIF_H_
@@ -20,5 +21,4 @@ void sel_netif_flush(void);
int sel_netif_sid(struct net *ns, int ifindex, u32 *sid);
-#endif /* _SELINUX_NETIF_H_ */
-
+#endif /* _SELINUX_NETIF_H_ */
diff --git a/security/selinux/include/netlabel.h b/security/selinux/include/netlabel.h
index 4d0456d3d4593..5731c0dcd3e8f 100644
--- a/security/selinux/include/netlabel.h
+++ b/security/selinux/include/netlabel.h
@@ -32,25 +32,19 @@ void selinux_netlbl_err(struct sk_buff *skb, u16 family, int error,
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);
+ 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,
@@ -62,44 +56,40 @@ static inline void selinux_netlbl_cache_invalidate(void)
return;
}
-static inline void selinux_netlbl_err(struct sk_buff *skb,
- u16 family,
- 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_sctp_assoc_request(struct sctp_association *asoc,
- struct sk_buff *skb)
+static inline int
+selinux_netlbl_sctp_assoc_request(struct sctp_association *asoc,
+ struct sk_buff *skb)
{
return 0;
}
@@ -117,21 +107,18 @@ static inline void selinux_netlbl_sctp_sk_clone(struct sock *sk,
{
return;
}
-static inline int selinux_netlbl_socket_post_create(struct sock *sk,
- u16 family)
+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;
}
diff --git a/security/selinux/include/objsec.h b/security/selinux/include/objsec.h
index 8159fd53c3de2..dea1d6f3ed2d3 100644
--- a/security/selinux/include/objsec.h
+++ b/security/selinux/include/objsec.h
@@ -13,6 +13,7 @@
* Copyright (C) 2003 Red Hat, Inc., James Morris <jmorris@redhat.com>
* Copyright (C) 2016 Mellanox Technologies
*/
+
#ifndef _SELINUX_OBJSEC_H_
#define _SELINUX_OBJSEC_H_
@@ -29,122 +30,122 @@
#include "avc.h"
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 */
+ 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;
enum label_initialized {
- LABEL_INVALID, /* invalid or not initialized */
- LABEL_INITIALIZED, /* 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 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 {
- 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 */
+ 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 {
- struct net *ns; /* network namespace */
- int ifindex; /* device index */
- u32 sid; /* SID for this interface */
+ 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 */
- enum { /* SCTP association state */
- SCTP_ASSOC_UNSET = 0,
- SCTP_ASSOC_SET,
+ 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 */
};
struct ib_security_struct {
- u32 sid; /* SID of the queue pair or MAD agent */
+ 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 */
+ 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 */
+ u32 sid; /* SID of bpf obj creator */
};
struct perf_event_security_struct {
- u32 sid; /* SID of perf_event obj creator */
+ u32 sid; /* SID of perf_event obj creator */
};
extern struct lsm_blob_sizes selinux_blob_sizes;
@@ -158,22 +159,22 @@ 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)
+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)
+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)
+static inline struct ipc_security_struct *
+selinux_ipc(const struct kern_ipc_perm *ipc)
{
return ipc->security + selinux_blob_sizes.lbs_ipc;
}
@@ -188,8 +189,8 @@ static inline u32 current_sid(void)
return tsec->sid;
}
-static inline struct superblock_security_struct *selinux_superblock(
- const struct super_block *superblock)
+static inline struct superblock_security_struct *
+selinux_superblock(const struct super_block *superblock)
{
return superblock->s_security + selinux_blob_sizes.lbs_superblock;
}
diff --git a/security/selinux/include/policycap.h b/security/selinux/include/policycap.h
index f35d3458e71de..dc3674eb29c18 100644
--- a/security/selinux/include/policycap.h
+++ b/security/selinux/include/policycap.h
@@ -1,4 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0 */
+
#ifndef _SELINUX_POLICYCAP_H_
#define _SELINUX_POLICYCAP_H_
@@ -12,6 +13,7 @@ enum {
POLICYDB_CAP_NNP_NOSUID_TRANSITION,
POLICYDB_CAP_GENFS_SECLABEL_SYMLINKS,
POLICYDB_CAP_IOCTL_SKIP_CLOEXEC,
+ POLICYDB_CAP_USERSPACE_INITIAL_CONTEXT,
__POLICYDB_CAP_MAX
};
#define POLICYDB_CAP_MAX (__POLICYDB_CAP_MAX - 1)
diff --git a/security/selinux/include/policycap_names.h b/security/selinux/include/policycap_names.h
index 49bbe120d1735..2cffcc1ce8519 100644
--- a/security/selinux/include/policycap_names.h
+++ b/security/selinux/include/policycap_names.h
@@ -1,9 +1,11 @@
/* 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",
@@ -14,6 +16,8 @@ const char *const selinux_policycap_names[__POLICYDB_CAP_MAX] = {
"nnp_nosuid_transition",
"genfs_seclabel_symlinks",
"ioctl_skip_cloexec",
+ "userspace_initial_context",
};
+/* clang-format on */
#endif /* _SELINUX_POLICYCAP_NAMES_H_ */
diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h
index a9de89af8fdc5..289bf9233f714 100644
--- a/security/selinux/include/security.h
+++ b/security/selinux/include/security.h
@@ -21,57 +21,57 @@
#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_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_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 */
/* Range of policy versions we understand*/
-#define POLICYDB_VERSION_MIN POLICYDB_VERSION_BASE
-#define POLICYDB_VERSION_MAX POLICYDB_VERSION_COMP_FTRANS
+#define POLICYDB_VERSION_MIN POLICYDB_VERSION_BASE
+#define POLICYDB_VERSION_MAX POLICYDB_VERSION_COMP_FTRANS
/* 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 0x0100
-#define SE_SBPROC 0x0200
-#define SE_SBGENFS 0x0400
-#define SE_SBGENFS_XATTR 0x0800
-#define SE_SBNATIVE 0x1000
+#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 ROOTCONTEXT_STR "rootcontext"
#define DEFCONTEXT_STR "defcontext"
-#define SECLABEL_STR "seclabel"
+#define SECLABEL_STR "seclabel"
struct netlbl_lsm_secattr;
@@ -81,11 +81,11 @@ 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
struct selinux_policy;
@@ -189,6 +189,12 @@ static inline bool selinux_policycap_ioctl_skip_cloexec(void)
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]);
+}
+
struct selinux_policy_convert_data;
struct selinux_load_state {
@@ -214,12 +220,12 @@ struct av_decision {
u32 flags;
};
-#define XPERMS_ALLOWED 1
+#define XPERMS_ALLOWED 1
#define XPERMS_AUDITALLOW 2
-#define XPERMS_DONTAUDIT 4
+#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)))
+#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];
};
@@ -233,23 +239,22 @@ struct extended_perms_decision {
};
struct extended_perms {
- u16 len; /* length associated decision chain */
+ u16 len; /* length associated decision chain */
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
-void security_compute_av(u32 ssid, u32 tsid,
- u16 tclass, struct av_decision *avd,
+void security_compute_av(u32 ssid, u32 tsid, u16 tclass,
+ struct av_decision *avd,
struct extended_perms *xperms);
-void security_compute_xperms_decision(u32 ssid, u32 tsid, u16 tclass,
- u8 driver,
+void security_compute_xperms_decision(u32 ssid, u32 tsid, u16 tclass, u8 driver,
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);
@@ -288,8 +293,7 @@ int security_ib_endport_sid(const char *dev_name, u8 port_num, u32 *out_sid);
int security_netif_sid(char *name, u32 *if_sid);
-int security_node_sid(u16 domain, void *addr, u32 addrlen,
- u32 *out_sid);
+int security_node_sid(u16 domain, void *addr, u32 addrlen, u32 *out_sid);
int security_validate_transition(u32 oldsid, u32 newsid, u32 tasksid,
u16 tclass);
@@ -301,50 +305,47 @@ int security_bounded_transition(u32 oldsid, u32 newsid);
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(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_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_genfs_sid(const char *fstype, const char *path, u16 sclass,
u32 *sid);
-int selinux_policy_genfs_sid(struct selinux_policy *policy,
- const char *fstype, const char *path, 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;
}
@@ -357,13 +358,13 @@ 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 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 */
+ 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.
*/
diff --git a/security/selinux/include/xfrm.h b/security/selinux/include/xfrm.h
index c758398602007..de485556ae29c 100644
--- a/security/selinux/include/xfrm.h
+++ b/security/selinux/include/xfrm.h
@@ -5,6 +5,7 @@
* Author : Trent Jaeger, <jaegert@us.ibm.com>
* Updated : Venkat Yekkirala, <vyekkirala@TrustedCS.com>
*/
+
#ifndef _SELINUX_XFRM_H_
#define _SELINUX_XFRM_H_
@@ -13,8 +14,7 @@
#include <net/xfrm.h>
int selinux_xfrm_policy_alloc(struct xfrm_sec_ctx **ctxp,
- struct xfrm_user_sec_ctx *uctx,
- gfp_t gfp);
+ 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);
diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c
index 6c596ae7fef94..0619a1cbbfbe4 100644
--- a/security/selinux/selinuxfs.c
+++ b/security/selinux/selinuxfs.c
@@ -336,12 +336,9 @@ static struct dentry *sel_make_dir(struct dentry *dir, const char *name,
unsigned long *ino);
/* declaration for sel_make_policy_nodes */
-static struct dentry *sel_make_disconnected_dir(struct super_block *sb,
+static struct dentry *sel_make_swapover_dir(struct super_block *sb,
unsigned long *ino);
-/* declaration for sel_make_policy_nodes */
-static void sel_remove_entries(struct dentry *de);
-
static ssize_t sel_read_mls(struct file *filp, char __user *buf,
size_t count, loff_t *ppos)
{
@@ -508,13 +505,13 @@ static int sel_make_policy_nodes(struct selinux_fs_info *fsi,
struct selinux_policy *newpolicy)
{
int ret = 0;
- struct dentry *tmp_parent, *tmp_bool_dir, *tmp_class_dir, *old_dentry;
- unsigned int tmp_bool_num, old_bool_num;
- char **tmp_bool_names, **old_bool_names;
- int *tmp_bool_values, *old_bool_values;
+ struct dentry *tmp_parent, *tmp_bool_dir, *tmp_class_dir;
+ unsigned int bool_num = 0;
+ char **bool_names = NULL;
+ int *bool_values = NULL;
unsigned long tmp_ino = fsi->last_ino; /* Don't increment last_ino in this function */
- tmp_parent = sel_make_disconnected_dir(fsi->sb, &tmp_ino);
+ tmp_parent = sel_make_swapover_dir(fsi->sb, &tmp_ino);
if (IS_ERR(tmp_parent))
return PTR_ERR(tmp_parent);
@@ -532,8 +529,8 @@ static int sel_make_policy_nodes(struct selinux_fs_info *fsi,
goto out;
}
- ret = sel_make_bools(newpolicy, tmp_bool_dir, &tmp_bool_num,
- &tmp_bool_names, &tmp_bool_values);
+ ret = sel_make_bools(newpolicy, tmp_bool_dir, &bool_num,
+ &bool_names, &bool_values);
if (ret)
goto out;
@@ -542,38 +539,30 @@ static int sel_make_policy_nodes(struct selinux_fs_info *fsi,
if (ret)
goto out;
+ lock_rename(tmp_parent, fsi->sb->s_root);
+
/* booleans */
- old_dentry = fsi->bool_dir;
- lock_rename(tmp_bool_dir, old_dentry);
d_exchange(tmp_bool_dir, fsi->bool_dir);
- old_bool_num = fsi->bool_num;
- old_bool_names = fsi->bool_pending_names;
- old_bool_values = fsi->bool_pending_values;
-
- fsi->bool_num = tmp_bool_num;
- fsi->bool_pending_names = tmp_bool_names;
- fsi->bool_pending_values = tmp_bool_values;
-
- sel_remove_old_bool_data(old_bool_num, old_bool_names, old_bool_values);
+ swap(fsi->bool_num, bool_num);
+ swap(fsi->bool_pending_names, bool_names);
+ swap(fsi->bool_pending_values, bool_values);
fsi->bool_dir = tmp_bool_dir;
- unlock_rename(tmp_bool_dir, old_dentry);
/* classes */
- old_dentry = fsi->class_dir;
- lock_rename(tmp_class_dir, old_dentry);
d_exchange(tmp_class_dir, fsi->class_dir);
fsi->class_dir = tmp_class_dir;
- unlock_rename(tmp_class_dir, old_dentry);
+
+ unlock_rename(tmp_parent, fsi->sb->s_root);
out:
+ sel_remove_old_bool_data(bool_num, bool_names, bool_values);
/* Since the other temporary dirs are children of tmp_parent
* this will handle all the cleanup in the case of a failure before
* the swapover
*/
- sel_remove_entries(tmp_parent);
- dput(tmp_parent); /* d_genocide() only handles the children */
+ simple_recursive_removal(tmp_parent, NULL);
return ret;
}
@@ -1351,54 +1340,48 @@ static const struct file_operations sel_commit_bools_ops = {
.llseek = generic_file_llseek,
};
-static void sel_remove_entries(struct dentry *de)
-{
- d_genocide(de);
- shrink_dcache_parent(de);
-}
-
static int sel_make_bools(struct selinux_policy *newpolicy, struct dentry *bool_dir,
unsigned int *bool_num, char ***bool_pending_names,
int **bool_pending_values)
{
int ret;
- ssize_t len;
- struct dentry *dentry = NULL;
- struct inode *inode = NULL;
- struct inode_security_struct *isec;
- char **names = NULL, *page;
+ char **names, *page;
u32 i, num;
- int *values = NULL;
- u32 sid;
- ret = -ENOMEM;
page = (char *)get_zeroed_page(GFP_KERNEL);
if (!page)
- goto out;
+ return -ENOMEM;
- ret = security_get_bools(newpolicy, &num, &names, &values);
+ ret = security_get_bools(newpolicy, &num, &names, bool_pending_values);
if (ret)
goto out;
+ *bool_num = num;
+ *bool_pending_names = names;
+
for (i = 0; i < num; i++) {
- ret = -ENOMEM;
+ struct dentry *dentry;
+ struct inode *inode;
+ struct inode_security_struct *isec;
+ ssize_t len;
+ u32 sid;
+
+ len = snprintf(page, PAGE_SIZE, "/%s/%s", BOOL_DIR_NAME, names[i]);
+ if (len >= PAGE_SIZE) {
+ ret = -ENAMETOOLONG;
+ break;
+ }
dentry = d_alloc_name(bool_dir, names[i]);
- if (!dentry)
- goto out;
+ if (!dentry) {
+ ret = -ENOMEM;
+ break;
+ }
- ret = -ENOMEM;
inode = sel_make_inode(bool_dir->d_sb, S_IFREG | S_IRUGO | S_IWUSR);
if (!inode) {
dput(dentry);
- goto out;
- }
-
- ret = -ENAMETOOLONG;
- len = snprintf(page, PAGE_SIZE, "/%s/%s", BOOL_DIR_NAME, names[i]);
- if (len >= PAGE_SIZE) {
- dput(dentry);
- iput(inode);
- goto out;
+ ret = -ENOMEM;
+ break;
}
isec = selinux_inode(inode);
@@ -1416,23 +1399,8 @@ static int sel_make_bools(struct selinux_policy *newpolicy, struct dentry *bool_
inode->i_ino = i|SEL_BOOL_INO_OFFSET;
d_add(dentry, inode);
}
- *bool_num = num;
- *bool_pending_names = names;
- *bool_pending_values = values;
-
- free_page((unsigned long)page);
- return 0;
out:
free_page((unsigned long)page);
-
- if (names) {
- for (i = 0; i < num; i++)
- kfree(names[i]);
- kfree(names);
- }
- kfree(values);
- sel_remove_entries(bool_dir);
-
return ret;
}
@@ -1961,20 +1929,40 @@ static struct dentry *sel_make_dir(struct dentry *dir, const char *name,
return dentry;
}
-static struct dentry *sel_make_disconnected_dir(struct super_block *sb,
+static int reject_all(struct mnt_idmap *idmap, struct inode *inode, int mask)
+{
+ return -EPERM; // no access for anyone, root or no root.
+}
+
+static const struct inode_operations swapover_dir_inode_operations = {
+ .lookup = simple_lookup,
+ .permission = reject_all,
+};
+
+static struct dentry *sel_make_swapover_dir(struct super_block *sb,
unsigned long *ino)
{
- struct inode *inode = sel_make_inode(sb, S_IFDIR | S_IRUGO | S_IXUGO);
+ struct dentry *dentry = d_alloc_name(sb->s_root, ".swapover");
+ struct inode *inode;
- if (!inode)
+ if (!dentry)
return ERR_PTR(-ENOMEM);
- inode->i_op = &simple_dir_inode_operations;
- inode->i_fop = &simple_dir_operations;
+ inode = sel_make_inode(sb, S_IFDIR);
+ if (!inode) {
+ dput(dentry);
+ return ERR_PTR(-ENOMEM);
+ }
+
+ inode->i_op = &swapover_dir_inode_operations;
inode->i_ino = ++(*ino);
/* directory inodes start off with i_nlink == 2 (for "." entry) */
inc_nlink(inode);
- return d_obtain_alias(inode);
+ inode_lock(sb->s_root->d_inode);
+ d_add(dentry, inode);
+ inc_nlink(sb->s_root->d_inode);
+ inode_unlock(sb->s_root->d_inode);
+ return dentry;
}
#define NULL_FILE_NAME "null"
diff --git a/security/selinux/ss/avtab.c b/security/selinux/ss/avtab.c
index 8751a602ead2a..697eb4352439f 100644
--- a/security/selinux/ss/avtab.c
+++ b/security/selinux/ss/avtab.c
@@ -96,12 +96,34 @@ avtab_insert_node(struct avtab *h, struct avtab_node **dst,
return newnode;
}
+static int avtab_node_cmp(const struct avtab_key *key1,
+ const struct avtab_key *key2)
+{
+ u16 specified = key1->specified & ~(AVTAB_ENABLED|AVTAB_ENABLED_OLD);
+
+ if (key1->source_type == key2->source_type &&
+ key1->target_type == key2->target_type &&
+ key1->target_class == key2->target_class &&
+ (specified & key2->specified))
+ return 0;
+ if (key1->source_type < key2->source_type)
+ return -1;
+ if (key1->source_type == key2->source_type &&
+ key1->target_type < key2->target_type)
+ return -1;
+ if (key1->source_type == key2->source_type &&
+ key1->target_type == key2->target_type &&
+ key1->target_class < key2->target_class)
+ return -1;
+ return 1;
+}
+
static int avtab_insert(struct avtab *h, const struct avtab_key *key,
const struct avtab_datum *datum)
{
u32 hvalue;
struct avtab_node *prev, *cur, *newnode;
- u16 specified = key->specified & ~(AVTAB_ENABLED|AVTAB_ENABLED_OLD);
+ int cmp;
if (!h || !h->nslot || h->nel == U32_MAX)
return -EINVAL;
@@ -110,23 +132,11 @@ static int avtab_insert(struct avtab *h, const struct avtab_key *key,
for (prev = NULL, cur = h->htable[hvalue];
cur;
prev = cur, cur = cur->next) {
- if (key->source_type == cur->key.source_type &&
- key->target_type == cur->key.target_type &&
- key->target_class == cur->key.target_class &&
- (specified & cur->key.specified)) {
- /* extended perms may not be unique */
- if (specified & AVTAB_XPERMS)
- break;
+ cmp = avtab_node_cmp(key, &cur->key);
+ /* extended perms may not be unique */
+ if (cmp == 0 && !(key->specified & AVTAB_XPERMS))
return -EEXIST;
- }
- if (key->source_type < cur->key.source_type)
- break;
- if (key->source_type == cur->key.source_type &&
- key->target_type < cur->key.target_type)
- break;
- if (key->source_type == cur->key.source_type &&
- key->target_type == cur->key.target_type &&
- key->target_class < cur->key.target_class)
+ if (cmp <= 0)
break;
}
@@ -148,7 +158,7 @@ struct avtab_node *avtab_insert_nonunique(struct avtab *h,
{
u32 hvalue;
struct avtab_node *prev, *cur;
- u16 specified = key->specified & ~(AVTAB_ENABLED|AVTAB_ENABLED_OLD);
+ int cmp;
if (!h || !h->nslot || h->nel == U32_MAX)
return NULL;
@@ -156,19 +166,8 @@ struct avtab_node *avtab_insert_nonunique(struct avtab *h,
for (prev = NULL, cur = h->htable[hvalue];
cur;
prev = cur, cur = cur->next) {
- if (key->source_type == cur->key.source_type &&
- key->target_type == cur->key.target_type &&
- key->target_class == cur->key.target_class &&
- (specified & cur->key.specified))
- break;
- if (key->source_type < cur->key.source_type)
- break;
- if (key->source_type == cur->key.source_type &&
- key->target_type < cur->key.target_type)
- break;
- if (key->source_type == cur->key.source_type &&
- key->target_type == cur->key.target_type &&
- key->target_class < cur->key.target_class)
+ cmp = avtab_node_cmp(key, &cur->key);
+ if (cmp <= 0)
break;
}
return avtab_insert_node(h, prev ? &prev->next : &h->htable[hvalue],
@@ -183,7 +182,7 @@ struct avtab_node *avtab_search_node(struct avtab *h,
{
u32 hvalue;
struct avtab_node *cur;
- u16 specified = key->specified & ~(AVTAB_ENABLED|AVTAB_ENABLED_OLD);
+ int cmp;
if (!h || !h->nslot)
return NULL;
@@ -191,20 +190,10 @@ struct avtab_node *avtab_search_node(struct avtab *h,
hvalue = avtab_hash(key, h->mask);
for (cur = h->htable[hvalue]; cur;
cur = cur->next) {
- if (key->source_type == cur->key.source_type &&
- key->target_type == cur->key.target_type &&
- key->target_class == cur->key.target_class &&
- (specified & cur->key.specified))
+ cmp = avtab_node_cmp(key, &cur->key);
+ if (cmp == 0)
return cur;
-
- if (key->source_type < cur->key.source_type)
- break;
- if (key->source_type == cur->key.source_type &&
- key->target_type < cur->key.target_type)
- break;
- if (key->source_type == cur->key.source_type &&
- key->target_type == cur->key.target_type &&
- key->target_class < cur->key.target_class)
+ if (cmp < 0)
break;
}
return NULL;
@@ -213,27 +202,19 @@ struct avtab_node *avtab_search_node(struct avtab *h,
struct avtab_node*
avtab_search_node_next(struct avtab_node *node, u16 specified)
{
+ struct avtab_key tmp_key;
struct avtab_node *cur;
+ int cmp;
if (!node)
return NULL;
-
- specified &= ~(AVTAB_ENABLED|AVTAB_ENABLED_OLD);
+ tmp_key = node->key;
+ tmp_key.specified = specified;
for (cur = node->next; cur; cur = cur->next) {
- if (node->key.source_type == cur->key.source_type &&
- node->key.target_type == cur->key.target_type &&
- node->key.target_class == cur->key.target_class &&
- (specified & cur->key.specified))
+ cmp = avtab_node_cmp(&tmp_key, &cur->key);
+ if (cmp == 0)
return cur;
-
- if (node->key.source_type < cur->key.source_type)
- break;
- if (node->key.source_type == cur->key.source_type &&
- node->key.target_type < cur->key.target_type)
- break;
- if (node->key.source_type == cur->key.source_type &&
- node->key.target_type == cur->key.target_type &&
- node->key.target_class < cur->key.target_class)
+ if (cmp < 0)
break;
}
return NULL;
diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c
index 595a435ea9c85..3b19ad28c9223 100644
--- a/security/selinux/ss/policydb.c
+++ b/security/selinux/ss/policydb.c
@@ -409,16 +409,9 @@ out:
static u32 filenametr_hash(const void *k)
{
const struct filename_trans_key *ft = k;
- unsigned long hash;
- unsigned int byte_num;
- unsigned char focus;
+ unsigned long salt = ft->ttype ^ ft->tclass;
- hash = ft->ttype ^ ft->tclass;
-
- byte_num = 0;
- while ((focus = ft->name[byte_num++]))
- hash = partial_name_hash(focus, hash);
- return hash;
+ return full_name_hash((void *)salt, ft->name, strlen(ft->name));
}
static int filenametr_cmp(const void *k1, const void *k2)
@@ -864,6 +857,8 @@ void policydb_destroy(struct policydb *p)
int policydb_load_isids(struct policydb *p, struct sidtab *s)
{
struct ocontext *head, *c;
+ bool isid_init_supported = ebitmap_get_bit(&p->policycaps,
+ POLICYDB_CAP_USERSPACE_INITIAL_CONTEXT);
int rc;
rc = sidtab_init(s);
@@ -887,6 +882,13 @@ int policydb_load_isids(struct policydb *p, struct sidtab *s)
if (!name)
continue;
+ /*
+ * Also ignore SECINITSID_INIT if the policy doesn't declare
+ * support for it
+ */
+ if (sid == SECINITSID_INIT && !isid_init_supported)
+ continue;
+
rc = sidtab_set_initial(s, sid, &c->context[0]);
if (rc) {
pr_err("SELinux: unable to load initial SID %s.\n",
@@ -894,6 +896,24 @@ int policydb_load_isids(struct policydb *p, struct sidtab *s)
sidtab_destroy(s);
return rc;
}
+
+ /*
+ * If the policy doesn't support the "userspace_initial_context"
+ * capability, set SECINITSID_INIT to the same context as
+ * SECINITSID_KERNEL. This ensures the same behavior as before
+ * the reintroduction of SECINITSID_INIT, where all tasks
+ * started before policy load would initially get the context
+ * corresponding to SECINITSID_KERNEL.
+ */
+ if (sid == SECINITSID_KERNEL && !isid_init_supported) {
+ rc = sidtab_set_initial(s, SECINITSID_INIT, &c->context[0]);
+ if (rc) {
+ pr_err("SELinux: unable to load initial SID %s.\n",
+ name);
+ sidtab_destroy(s);
+ return rc;
+ }
+ }
}
return 0;
}
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index 1eeffc66ea7d7..e88b1b6c4adbb 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -1322,8 +1322,19 @@ static int security_sid_to_context_core(u32 sid, char **scontext,
if (!selinux_initialized()) {
if (sid <= SECINITSID_NUM) {
char *scontextp;
- const char *s = initial_sid_to_string[sid];
+ const char *s;
+ /*
+ * Before the policy is loaded, translate
+ * SECINITSID_INIT to "kernel", because systemd and
+ * libselinux < 2.6 take a getcon_raw() result that is
+ * both non-null and not "kernel" to mean that a policy
+ * is already loaded.
+ */
+ if (sid == SECINITSID_INIT)
+ sid = SECINITSID_KERNEL;
+
+ s = initial_sid_to_string[sid];
if (!s)
return -EINVAL;
*scontext_len = strlen(s) + 1;