summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--security/selinux/hooks.c73
-rw-r--r--security/selinux/include/classmap.h68
-rw-r--r--security/selinux/include/security.h3
-rw-r--r--security/selinux/selinuxfs.c2
-rw-r--r--security/selinux/ss/services.c3
5 files changed, 147 insertions, 2 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index c7c6619431d5..74cd3a689cf8 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -1268,6 +1268,8 @@ static inline int default_protocol_dgram(int protocol)
static inline u16 socket_type_to_security_class(int family, int type, int protocol)
{
+ int extsockclass = selinux_policycap_extsockclass;
+
switch (family) {
case PF_UNIX:
switch (type) {
@@ -1282,13 +1284,18 @@ static inline u16 socket_type_to_security_class(int family, int type, int protoc
case PF_INET6:
switch (type) {
case SOCK_STREAM:
+ case SOCK_SEQPACKET:
if (default_protocol_stream(protocol))
return SECCLASS_TCP_SOCKET;
+ else if (extsockclass && protocol == IPPROTO_SCTP)
+ return SECCLASS_SCTP_SOCKET;
else
return SECCLASS_RAWIP_SOCKET;
case SOCK_DGRAM:
if (default_protocol_dgram(protocol))
return SECCLASS_UDP_SOCKET;
+ else if (extsockclass && protocol == IPPROTO_ICMP)
+ return SECCLASS_ICMP_SOCKET;
else
return SECCLASS_RAWIP_SOCKET;
case SOCK_DCCP:
@@ -1342,6 +1349,72 @@ static inline u16 socket_type_to_security_class(int family, int type, int protoc
return SECCLASS_APPLETALK_SOCKET;
}
+ if (extsockclass) {
+ switch (family) {
+ case PF_AX25:
+ return SECCLASS_AX25_SOCKET;
+ case PF_IPX:
+ return SECCLASS_IPX_SOCKET;
+ case PF_NETROM:
+ return SECCLASS_NETROM_SOCKET;
+ case PF_BRIDGE:
+ return SECCLASS_BRIDGE_SOCKET;
+ case PF_ATMPVC:
+ return SECCLASS_ATMPVC_SOCKET;
+ case PF_X25:
+ return SECCLASS_X25_SOCKET;
+ case PF_ROSE:
+ return SECCLASS_ROSE_SOCKET;
+ case PF_DECnet:
+ return SECCLASS_DECNET_SOCKET;
+ case PF_ATMSVC:
+ return SECCLASS_ATMSVC_SOCKET;
+ case PF_RDS:
+ return SECCLASS_RDS_SOCKET;
+ case PF_IRDA:
+ return SECCLASS_IRDA_SOCKET;
+ case PF_PPPOX:
+ return SECCLASS_PPPOX_SOCKET;
+ case PF_LLC:
+ return SECCLASS_LLC_SOCKET;
+ case PF_IB:
+ return SECCLASS_IB_SOCKET;
+ case PF_MPLS:
+ return SECCLASS_MPLS_SOCKET;
+ case PF_CAN:
+ return SECCLASS_CAN_SOCKET;
+ case PF_TIPC:
+ return SECCLASS_TIPC_SOCKET;
+ case PF_BLUETOOTH:
+ return SECCLASS_BLUETOOTH_SOCKET;
+ case PF_IUCV:
+ return SECCLASS_IUCV_SOCKET;
+ case PF_RXRPC:
+ return SECCLASS_RXRPC_SOCKET;
+ case PF_ISDN:
+ return SECCLASS_ISDN_SOCKET;
+ case PF_PHONET:
+ return SECCLASS_PHONET_SOCKET;
+ case PF_IEEE802154:
+ return SECCLASS_IEEE802154_SOCKET;
+ case PF_CAIF:
+ return SECCLASS_CAIF_SOCKET;
+ case PF_ALG:
+ return SECCLASS_ALG_SOCKET;
+ case PF_NFC:
+ return SECCLASS_NFC_SOCKET;
+ case PF_VSOCK:
+ return SECCLASS_VSOCK_SOCKET;
+ case PF_KCM:
+ return SECCLASS_KCM_SOCKET;
+ case PF_QIPCRTR:
+ return SECCLASS_QIPCRTR_SOCKET;
+#if PF_MAX > 43
+#error New address family defined, please update this function.
+#endif
+ }
+ }
+
return SECCLASS_SOCKET;
}
diff --git a/security/selinux/include/classmap.h b/security/selinux/include/classmap.h
index 13ae49b0baa0..0dfd26d0b8d8 100644
--- a/security/selinux/include/classmap.h
+++ b/security/selinux/include/classmap.h
@@ -171,5 +171,73 @@ struct security_class_mapping secclass_map[] = {
{ COMMON_CAP_PERMS, NULL } },
{ "cap2_userns",
{ COMMON_CAP2_PERMS, NULL } },
+ { "sctp_socket",
+ { COMMON_SOCK_PERMS,
+ "node_bind", 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 } },
+ { "bridge_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 } },
+ { "ib_socket",
+ { COMMON_SOCK_PERMS, NULL } },
+ { "mpls_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 } },
{ NULL }
};
+
+#if PF_MAX > 43
+#error New address family defined, please update secclass_map.
+#endif
diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h
index 308a286c6cbe..beaa14b8b6cf 100644
--- a/security/selinux/include/security.h
+++ b/security/selinux/include/security.h
@@ -69,7 +69,7 @@ extern int selinux_enabled;
enum {
POLICYDB_CAPABILITY_NETPEER,
POLICYDB_CAPABILITY_OPENPERM,
- POLICYDB_CAPABILITY_REDHAT1,
+ POLICYDB_CAPABILITY_EXTSOCKCLASS,
POLICYDB_CAPABILITY_ALWAYSNETWORK,
__POLICYDB_CAPABILITY_MAX
};
@@ -77,6 +77,7 @@ enum {
extern int selinux_policycap_netpeer;
extern int selinux_policycap_openperm;
+extern int selinux_policycap_extsockclass;
extern int selinux_policycap_alwaysnetwork;
/*
diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c
index cf9293e01fc1..0aac402a0f11 100644
--- a/security/selinux/selinuxfs.c
+++ b/security/selinux/selinuxfs.c
@@ -45,7 +45,7 @@
static char *policycap_names[] = {
"network_peer_controls",
"open_perms",
- "redhat1",
+ "extended_socket_class",
"always_check_network"
};
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index 082b20c78363..a70fcee9824b 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -72,6 +72,7 @@
int selinux_policycap_netpeer;
int selinux_policycap_openperm;
+int selinux_policycap_extsockclass;
int selinux_policycap_alwaysnetwork;
static DEFINE_RWLOCK(policy_rwlock);
@@ -1988,6 +1989,8 @@ static void security_load_policycaps(void)
POLICYDB_CAPABILITY_NETPEER);
selinux_policycap_openperm = ebitmap_get_bit(&policydb.policycaps,
POLICYDB_CAPABILITY_OPENPERM);
+ selinux_policycap_extsockclass = ebitmap_get_bit(&policydb.policycaps,
+ POLICYDB_CAPABILITY_EXTSOCKCLASS);
selinux_policycap_alwaysnetwork = ebitmap_get_bit(&policydb.policycaps,
POLICYDB_CAPABILITY_ALWAYSNETWORK);
}