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); }