On 12/01/2016 10:57 AM, Stephen Smalley wrote:
> On 12/01/2016 10:07 AM, Stephen Smalley wrote:
>> Extend SELinux to support distinctions among all network address families
>> implemented by the kernel by defining new socket security classes
>> and mapping to them. Otherwise, many sockets are mapped to the generic
>> socket class and are indistinguishable in policy.  This has come up
>> previously with regard to selectively allowing access to bluetooth sockets,
>> and more recently with regard to selectively allowing access to AF_ALG
>> sockets.  Guido Trentalancia submitted a patch that took a similar approach
>> to add only support for distinguishing AF_ALG sockets, but this generalizes
>> his approach to handle all address families implemented by the kernel.
>> Socket security classes were not defined for AF_* values that are reserved
>> but unimplemented in the kernel, e.g. AF_NETBEUI, AF_SECURITY, AF_ECONET,
>> AF_SNA, AF_WANPIPE.
>>
>> Backward compatibility is provided by only enabling the finer-grained
>> socket classes if a new policy capability is set in the policy; older
>> policies will behave as before.  The legacy redhat1 policy capability
>> that was only ever used in testing within Fedora for ptrace_child
>> is reclaimed for this purpose; as far as I can tell, this policy
>> capability is not enabled in any supported distro policy.
>>
>> Add a pair of conditional compilation guards to detect when new AF_* values
>> are added so that we can update SELinux accordingly rather than having to
>> belatedly update it long after new address families are introduced.
> 
> A couple of notes on this change:
> 
> - To fully test (beyond just confirming that it doesn't break anything
> when the policy capability is not defined), we'll need a patched
> libsepol and policy (and unfortunately it requires patching the base
> policy; can't be done via a policy module).  Can certainly provide those
> too but figured I'd wait to see the response to the kernel patch first.
> 
> - There is a potential cost to this change when/if it is enabled in
> policy, i.e. if we blindly allowing all of these new classes where we
> previously allowed the generic socket class, we'll end up with
> significant growth in policy avtab entries and in AVC entries (although
> only if they are in fact used), since those are per-class.  However, I
> wouldn't expect to do that except possibly for the unconfined domain;
> many of these classes won't need to be allowed at all for most domains.
> 
> - There is a slight compatibility issue.  While the policy capability
> ensures that we will not use the new socket classes with old policies,
> we don't presently support a way to refresh socket security classes upon
> a policy reload.  Hence, if you boot a kernel with a policy that has the
> capability disabled, and then later load a policy that has the
> capability enabled, any existing sockets won't be automatically moved
> into the new security classes; they will continue to be treated as
> having the generic socket security class.  I view this as a minor issue
> and unlikely to cause any breakage, because refpolicy is likely to
> merely add new rules for the new socket classes without removing the old
> rules on the generic socket security class to provide backward
> compatibility with kernels that predate this change.  Eventually we may
> be able to drop those rules, but not for quite some time.  In any event,
> be aware that taking full advantage of these new classes does require a
> reboot.

Note btw that this slight compatibility issue was also true of commit
6c6d2e9bde1c1c87a7ead806f8f5e2181d41a652 ("selinux: update netlink
socket classes"), which doesn't appear to have caused any problems in
practice.

> 
>>
>> Signed-off-by: Stephen Smalley <s...@tycho.nsa.gov>
>> ---
>>  security/selinux/hooks.c            | 67 
>> +++++++++++++++++++++++++++++++++++++
>>  security/selinux/include/classmap.h | 62 ++++++++++++++++++++++++++++++++++
>>  security/selinux/include/security.h |  3 +-
>>  security/selinux/selinuxfs.c        |  2 +-
>>  security/selinux/ss/services.c      |  3 ++
>>  5 files changed, 135 insertions(+), 2 deletions(-)
>>
>> diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
>> index 98a2e92..1ee2172 100644
>> --- a/security/selinux/hooks.c
>> +++ b/security/selinux/hooks.c
>> @@ -1342,6 +1342,73 @@ static inline u16 socket_type_to_security_class(int 
>> family, int type, int protoc
>>              return SECCLASS_APPLETALK_SOCKET;
>>      }
>>  
>> +    if (!selinux_policycap_extsockclass)
>> +            return SECCLASS_SOCKET;
>> +
>> +    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 e2d4ad3a..a11be76 100644
>> --- a/security/selinux/include/classmap.h
>> +++ b/security/selinux/include/classmap.h
>> @@ -169,5 +169,67 @@ struct security_class_mapping secclass_map[] = {
>>        { COMMON_CAP_PERMS, NULL } },
>>      { "cap2_userns",
>>        { COMMON_CAP2_PERMS, 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 308a286..beaa14b 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 cf9293e..0aac402 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 082b20c..a70fcee 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);
>>  }
>>
> 

_______________________________________________
Selinux mailing list
Selinux@tycho.nsa.gov
To unsubscribe, send email to selinux-le...@tycho.nsa.gov.
To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.

Reply via email to