The comedy of errors patchset (was: SELinux NetLabel updates)
Subsystems (3)
v3 cover The comedy of errors patchset (was: SELinux NetLabel updates)
This rev of the patchset solves both the original problem that Michal posted involving backwards compatibility with old SELinux policy as well as the problem Linus posted about the fix not working correctly when CONFIG_NETLABEL was not set. I also tried to fixup the #ifdefs in include/net/netlabel.h as suggested.
I've tested both of these patches, in order, and neither have caused problems (i.e. there shouldn't be any git bisect breakage issues if only the first patch is applied). I've also compiled both patches with and without CONFIG_NETLABEL and have not seen any problems.
Once again, thank you all for your patience.
Signature · 2 lines
paul moore linux security @ hp
PATCH v3 1/2 NetLabel: enable dynamic activation/deactivation of NetLabel/SELinux enforcement
Create a new NetLabel KAPI interface, netlbl_enabled(), which reports on the current runtime status of NetLabel based on the existing configuration. LSMs that make use of NetLabel, i.e. SELinux, can use this new function to determine if they should perform NetLabel access checks. This patch changes the NetLabel/SELinux glue code such that SELinux only enforces NetLabel related access checks when netlbl_enabled() returns true.
At present NetLabel is considered to be enabled when there is at least one labeled protocol configuration present. The result is that by default NetLabel is considered to be disabled, however, as soon as an administrator configured a CIPSO DOI definition NetLabel is enabled and SELinux starts enforcing NetLabel related access controls - including unlabeled packet controls.
This patch also tries to consolidate the multiple "#ifdef CONFIG_NETLABEL" blocks into a single block to ease future review as recommended by Linus.
--- include/net/netlabel.h | 62 ++++++++++++++++--------------------- net/netlabel/netlabel_cipso_v4.c | 5 +++ net/netlabel/netlabel_kapi.c | 21 ++++++++++++ net/netlabel/netlabel_mgmt.c | 65 +++++++++++++++++++++++++++++++++++++++ net/netlabel/netlabel_mgmt.h | 5 +++ security/selinux/netlabel.c | 8 ++++ 6 files changed, 131 insertions(+), 35 deletions(-)
include/net/netlabel.h +27 -35
@@ -144,10 +144,9 @@ struct netlbl_lsm_secattr { };/* -* LSM security attribute operations +* LSM security attribute operations (inline) */ -/** * netlbl_secattr_cache_alloc - Allocate and initialize a secattr cache * @flags: the memory allocation flags
@@ -283,6 +282,9 @@ static inline void netlbl_secattr_free(s }#ifdef CONFIG_NETLABEL +/* +* LSM security attribute operations +*/ int netlbl_secattr_catmap_walk (struct netlbl_lsm_secattr_catmap *catmap,u32 offset); int netlbl_secattr_catmap_walk_rng(struct netlbl_lsm_secattr_catmap *catmap,
@@ -294,6 +296,25 @@ int netlbl_secattr_catmap_setrng(structu32 start, u32 end, gfp_t flags); + +/* +* LSM protocol operations +*/ +int netlbl_enabled (void ); +int netlbl_sock_setattr (struct sock *sk, +const struct netlbl_lsm_secattr *secattr); +int netlbl_sock_getattr (struct sock *sk, +struct netlbl_lsm_secattr *secattr); +int netlbl_skbuff_getattr (const struct sk_buff *skb, +struct netlbl_lsm_secattr *secattr); +void netlbl_skbuff_err (struct sk_buff *skb,int error); + +/* +* LSM label mapping cache operations +*/ +void netlbl_cache_invalidate (void ); +int netlbl_cache_add (const struct sk_buff *skb, +const struct netlbl_lsm_secattr *secattr);#else static inline int netlbl_secattr_catmap_walk( struct netlbl_lsm_secattr_catmap *catmap,
@@ -301,14 +322,12 @@ static inline int netlbl_secattr_catmap_ {return -ENOENT ; } -static inline int netlbl_secattr_catmap_walk_rng (struct netlbl_lsm_secattr_catmap *catmap,u32 offset) {return -ENOENT ; } - static inline int netlbl_secattr_catmap_setbit( struct netlbl_lsm_secattr_catmap *catmap, u32 bit,
@@ -316,7 +335,6 @@ static inline int netlbl_secattr_catmap_ {return 0 ; } - static inline int netlbl_secattr_catmap_setrng( struct netlbl_lsm_secattr_catmap *catmap, u32 start,
@@ -325,59 +343,33 @@ static inline int netlbl_secattr_catmap_ {return 0 ; } -#endif - -/* -* LSM protocol operations -*/ - -#ifdef CONFIG_NETLABEL -int netlbl_sock_setattr (struct sock *sk, -const struct netlbl_lsm_secattr *secattr); -int netlbl_sock_getattr (struct sock *sk, -struct netlbl_lsm_secattr *secattr); -int netlbl_skbuff_getattr (const struct sk_buff *skb, -struct netlbl_lsm_secattr *secattr); -void netlbl_skbuff_err (struct sk_buff *skb,int error); -#else +static inline int netlbl_enabled (void ) +{ +return 0 ; +}static inline int netlbl_sock_setattr (struct sock *sk,const struct netlbl_lsm_secattr *secattr) {return -ENOSYS ; } -static inline int netlbl_sock_getattr (struct sock *sk,struct netlbl_lsm_secattr *secattr) {return -ENOSYS ; } -static inline int netlbl_skbuff_getattr (const struct sk_buff *skb,struct netlbl_lsm_secattr *secattr) {return -ENOSYS ; } -static inline void netlbl_skbuff_err (struct sk_buff *skb,int error) {return ; } -#endif /* CONFIG_NETLABEL */ - -/* -* LSM label mapping cache operations -*/ - -#ifdef CONFIG_NETLABEL -void netlbl_cache_invalidate (void ); -int netlbl_cache_add (const struct sk_buff *skb, -const struct netlbl_lsm_secattr *secattr); -#else static inline void netlbl_cache_invalidate (void ) {return ; } -static inline int netlbl_cache_add (const struct sk_buff *skb,const struct netlbl_lsm_secattr *secattr) {
net/netlabel/netlabel_cipso_v4.c +5 -0
@@ -41,6 +41,7 @@#include "netlabel_user.h" #include "netlabel_cipso_v4.h" +#include "netlabel_mgmt.h" /* Argument struct for cipso_v4_doi_walk() */ struct netlbl_cipsov4_doiwalk_arg {
@@ -419,6 +420,8 @@ static int netlbl_cipsov4_add(struct sk_ ret_val =netlbl_cipsov4_add_pass (info);break ; } +if (ret_val ==0 ) +netlbl_mgmt_protocount_inc (); audit_buf =netlbl_audit_start_common (AUDIT_MAC_CIPSOV4_ADD , &audit_info);
@@ -694,6 +697,8 @@ static int netlbl_cipsov4_remove(struct ret_val =cipso_v4_doi_remove (doi, &audit_info, netlbl_cipsov4_doi_free); +if (ret_val ==0 ) +netlbl_mgmt_protocount_dec (); audit_buf =netlbl_audit_start_common (AUDIT_MAC_CIPSOV4_DEL , &audit_info);
net/netlabel/netlabel_kapi.c +21 -0
@@ -38,6 +38,7 @@#include "netlabel_domainhash.h" #include "netlabel_unlabeled.h" #include "netlabel_user.h" +#include "netlabel_mgmt.h" /* * Security Attribute Functions
@@ -245,6 +246,26 @@ int netlbl_secattr_catmap_setrng(struct*/ /** +* netlbl_enabled - Determine if the NetLabel subsystem is enabled +* +* Description: +* The LSM can use this function to determine if it should use NetLabel +* security attributes in it's enforcement mechanism. Currently, NetLabel is +* considered to be enabled when it's configuration contains a valid setup for +* at least one labeled protocol (i.e. NetLabel can understand incoming +* labeled packets of at least one type); otherwise NetLabel is considered to +* be disabled. +* +*/ +int netlbl_enabled (void ) +{ +/* At some point we probably want to expose this mechanism to the user +* as well so that admins can toggle NetLabel regardless of the +* configuration */ +return (netlbl_mgmt_protocount_value () >0 ?1 :0 ); +} + +/** * netlbl_socket_setattr - Label a socket using the correct protocol * @sk: the socket to label * @secattr: the security attributes
net/netlabel/netlabel_mgmt.c +65 -0
77 lines not on this page · raw message
net/netlabel/netlabel_mgmt.h +5 -0
@@ -168,4 +168,9 @@ enum {/* NetLabel protocol functions */ int netlbl_mgmt_genl_init (void ); +/* NetLabel misc management functions */ +void netlbl_mgmt_protocount_inc (void ); +void netlbl_mgmt_protocount_dec (void ); +u32 netlbl_mgmt_protocount_value (void ); +#endif
security/selinux/netlabel.c +8 -0
@@ -155,6 +155,11 @@ int selinux_netlbl_skbuff_getsid(structint rc;struct netlbl_lsm_secattr secattr; +if (!netlbl_enabled ()) { + *sid =SECSID_NULL ; +return 0 ; + } +netlbl_secattr_init (&secattr); rc =netlbl_skbuff_getattr (skb, &secattr);if (rc ==0 && secattr.flags !=NETLBL_SECATTR_NONE )
@@ -298,6 +303,9 @@ int selinux_netlbl_sock_rcv_skb(struct su32 netlbl_sid;u32 recv_perm; +if (!netlbl_enabled ()) +return 0 ; + rc =selinux_netlbl_skbuff_getsid (skb,SECINITSID_UNLABELED , &netlbl_sid);
Signature · 2 lines
paul moore linux security @ hp
PATCH v3 2/2 SELinux: use SECINITSID_NETMSG instead of SECINITSID_UNLABELED for NetLabel
In reply to Paul MooreThese changes will make NetLabel behave like labeled IPsec where there is an access check for both labeled and unlabeled packets as well as providing the ability to restrict domains to receiving only labeled packets when NetLabel is in use. The changes to the policy are straight forward with the following necessary to receive labeled traffic (with SECINITSID_NETMSG defined as "netlabel_peer_t"):
allow mydom_t netlabel_peer_t:{ tcp_socket udp_socket rawip_socket } recvfrom;
The policy for unlabeled traffic would be:
allow mydom_t unlabeled_t:{ tcp_socket udp_socket rawip_socket } recvfrom;
These policy changes, as well as more general NetLabel support, are included in the latest SELinux Reference Policy release 20070629 or later. Users who make use of NetLabel are strongly encouraged to upgrade their policy to avoid network problems. Users who do not make use of NetLabel will not notice any difference.
--- security/selinux/hooks.c | 21 +++++++++++---------- security/selinux/netlabel.c | 41 ++++++++++++++++++++--------------------- 2 files changed, 31 insertions(+), 31 deletions(-)
security/selinux/hooks.c +11 -10
@@ -3129,17 +3129,19 @@ static int selinux_parse_skb(struct sk_b/** * selinux_skb_extlbl_sid - Determine the external label of a packet * @skb: the packet -* @base_sid: the SELinux SID to use as a context for MLS only external labels * @sid: the packet's SID * * Description: * Check the various different forms of external packet labeling and determine -* the external SID for the packet. +* the external SID for the packet. If only one form of external labeling is +* present then it is used, if both labeled IPsec and NetLabel labels are +* present then the SELinux type information is taken from the labeled IPsec +* SA and the MLS sensitivity label information is taken from the NetLabel +* security attributes. This bit of "magic" is done in the call to +* selinux_netlbl_skbuff_getsid(). * */ -static void selinux_skb_extlbl_sid (struct sk_buff *skb, -u32 base_sid, -u32 *sid) +static void selinux_skb_extlbl_sid (struct sk_buff *skb,u32 *sid) {u32 xfrm_sid;u32 nlbl_sid;
@@ -3147,10 +3149,9 @@ static void selinux_skb_extlbl_sid(strucselinux_skb_xfrm_sid (skb, &xfrm_sid);if (selinux_netlbl_skbuff_getsid (skb, (xfrm_sid ==SECSID_NULL ? - base_sid : xfrm_sid), +SECINITSID_NETMSG : xfrm_sid), &nlbl_sid) !=0 ) nlbl_sid =SECSID_NULL ; - *sid = (nlbl_sid ==SECSID_NULL ? xfrm_sid : nlbl_sid); }
@@ -3695,7 +3696,7 @@ static int selinux_socket_getpeersec_dgrif (sock && sock->sk->sk_family ==PF_UNIX )selinux_get_inode_sid (SOCK_INODE (sock), &peer_secid);else if (skb) -selinux_skb_extlbl_sid (skb,SECINITSID_UNLABELED , &peer_secid); +selinux_skb_extlbl_sid (skb, &peer_secid);if (peer_secid ==SECSID_NULL ) err = -EINVAL ;
@@ -3756,7 +3757,7 @@ static int selinux_inet_conn_request(stru32 newsid;u32 peersid; -selinux_skb_extlbl_sid (skb,SECINITSID_UNLABELED , &peersid); +selinux_skb_extlbl_sid (skb, &peersid);if (peersid ==SECSID_NULL ) { req->secid = sksec->sid; req->peer_secid =SECSID_NULL ;
@@ -3794,7 +3795,7 @@ static void selinux_inet_conn_establishe {struct sk_security_struct *sksec = sk->sk_security; -selinux_skb_extlbl_sid (skb,SECINITSID_UNLABELED , &sksec->peer_sid); +selinux_skb_extlbl_sid (skb, &sksec->peer_sid); } static void selinux_req_classify_flow(const struct request_sock *req,
security/selinux/netlabel.c +20 -21
77 lines not on this page · raw message
Signature · 2 lines
paul moore linux security @ hp