calipso: Add a label cache.
RFC PATCH v3 18/19 calipso: Add a label cache.
This works in exactly the same way as the CIPSO label cache. The idea is to allow the lsm to cache the result of a secattr lookup so that it doesn't need to perform the lookup for every skbuff.
It introduces two sysctl controls:
calipso_cache_enable - enables/disables the cache. calipso_cache_bucket_size - sets the size of a cache bucket.
Signed-off-by Huw Davies <[email protected]>
--- include/net/calipso.h | 6 + include/net/netlabel.h | 9 +- net/ipv6/calipso.c | 264 +++++++++++++++++++++++++++++++++++++++- net/ipv6/sysctl_net_ipv6.c | 19 +++ net/netlabel/netlabel_calipso.c | 38 ++++++ net/netlabel/netlabel_calipso.h | 3 + net/netlabel/netlabel_kapi.c | 24 +++- security/selinux/netlabel.c | 9 +- 8 files changed, 360 insertions(+), 12 deletions(-)
include/net/calipso.h +6 -0
@@ -62,6 +62,12 @@ struct calipso_doi {struct rcu_head rcu; }; +/* +* Sysctl Variables +*/ +extern int calipso_cache_enabled; +extern int calipso_cache_bucketsize; +#ifdef CONFIG_NETLABEL int __init calipso_init (void );void calipso_exit (void );
include/net/netlabel.h +7 -2
@@ -235,6 +235,8 @@ struct netlbl_lsm_secattr {* @skbuff_optptr: find option in packet * @skbuff_setattr: set the skbuff's attr * @skbuff_delattr: remove the skbuff's attr +* @cache_invalidate: invalidate cache +* @cache_add: add cache entry * * Description: * This structure is filled out by the CALIPSO engine and passed
@@ -269,6 +271,9 @@ struct netlbl_calipso_ops {const struct calipso_doi *doi_def, const struct netlbl_lsm_secattr *secattr);int (*skbuff_delattr)(struct sk_buff *skb); +void (*cache_invalidate)(void ); +int (*cache_add)(const unsigned char *calipso_ptr, +const struct netlbl_lsm_secattr *secattr); };/*
@@ -494,7 +499,7 @@ void netlbl_skbuff_err(struct sk_buff *skb, u16 family, int error, int gateway);* LSM label mapping cache operations */ void netlbl_cache_invalidate (void ); -int netlbl_cache_add (const struct sk_buff *skb, +int netlbl_cache_add (const struct sk_buff *skb,u16 family,const struct netlbl_lsm_secattr *secattr);/*
@@ -647,7 +652,7 @@ static inline void netlbl_cache_invalidate(void) {return ; } -static inline int netlbl_cache_add (const struct sk_buff *skb, +static inline int netlbl_cache_add (const struct sk_buff *skb,u16 family,const struct netlbl_lsm_secattr *secattr) {return 0 ;
net/ipv6/calipso.c +262 -2
291 lines not on this page · raw message
net/ipv6/sysctl_net_ipv6.c +19 -0
@@ -15,6 +15,9 @@#include <net/ipv6.h> #include <net/addrconf.h> #include <net/inet_frag.h> +#ifdef CONFIG_NETLABEL +#include <net/calipso.h> +#endif static int one =1 ;static int auto_flowlabels_min;
@@ -106,6 +109,22 @@ static struct ctl_table ipv6_rotable[] = { .proc_handler = proc_dointvec_minmax, .extra1 = &one }, +#ifdef CONFIG_NETLABEL + { + .procname = "calipso_cache_enable", + .data = &calipso_cache_enabled, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = proc_dointvec, + }, + { + .procname = "calipso_cache_bucket_size", + .data = &calipso_cache_bucketsize, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = proc_dointvec, + }, +#endif /* CONFIG_NETLABEL */ { } };
net/netlabel/netlabel_calipso.c +38 -0
@@ -700,3 +700,41 @@ int calipso_skbuff_delattr(struct sk_buff *skb) ret_val = ops->skbuff_delattr (skb);return ret_val; } + +/** +* calipso_cache_invalidate - Invalidates the current CALIPSO cache +* +* Description: +* Invalidates and frees any entries in the CALIPSO cache. Returns zero on +* success and negative values on failure. +* +*/ +void calipso_cache_invalidate (void ) +{ +const struct netlbl_calipso_ops *ops =netlbl_calipso_ops_get (); + +if (ops) + ops->cache_invalidate (); +} + +/** +* calipso_cache_add - Add an entry to the CALIPSO cache +* @calipso_ptr: the CALIPSO option +* @secattr: the packet's security attributes +* +* Description: +* Add a new entry into the CALIPSO label mapping cache. +* Returns zero on success, negative values on failure. +* +*/ +int calipso_cache_add (const unsigned char *calipso_ptr, +const struct netlbl_lsm_secattr *secattr) + +{ +int ret_val = -ENOMSG ; +const struct netlbl_calipso_ops *ops =netlbl_calipso_ops_get (); + +if (ops) + ret_val = ops->cache_add (calipso_ptr, secattr); +return ret_val; +}
net/netlabel/netlabel_calipso.h +3 -0
@@ -144,5 +144,8 @@ int calipso_skbuff_setattr(struct sk_buff *skb,const struct calipso_doi *doi_def, const struct netlbl_lsm_secattr *secattr);int calipso_skbuff_delattr (struct sk_buff *skb); +void calipso_cache_invalidate (void ); +int calipso_cache_add (const unsigned char *calipso_ptr, +const struct netlbl_lsm_secattr *secattr);#endif
net/netlabel/netlabel_kapi.c +19 -5
@@ -1282,11 +1282,15 @@ void netlbl_skbuff_err(struct sk_buff *skb, u16 family, int error, int gateway)void netlbl_cache_invalidate (void ) {cipso_v4_cache_invalidate (); +#if IS_ENABLED (CONFIG_IPV6 ) +calipso_cache_invalidate (); +#endif /* IPv6 */ }/** * netlbl_cache_add - Add an entry to a NetLabel protocol cache * @skb: the packet +* @family: the family * @secattr: the packet's security attributes * * Description:
@@ -1295,7 +1299,7 @@ void netlbl_cache_invalidate(void)* values on error. * */ -int netlbl_cache_add (const struct sk_buff *skb, +int netlbl_cache_add (const struct sk_buff *skb,u16 family,const struct netlbl_lsm_secattr *secattr) {unsigned char *ptr;
@@ -1303,10 +1307,20 @@ int netlbl_cache_add(const struct sk_buff *skb,if ((secattr->flags &NETLBL_SECATTR_CACHE ) ==0 )return -ENOMSG ; - ptr =cipso_v4_optptr (skb); -if (ptr) -return cipso_v4_cache_add (ptr, secattr); - +switch (family) { +case AF_INET : + ptr =cipso_v4_optptr (skb); +if (ptr) +return cipso_v4_cache_add (ptr, secattr); +break ; +#if IS_ENABLED (CONFIG_IPV6 ) +case AF_INET6 : + ptr =calipso_optptr (skb); +if (ptr) +return calipso_cache_add (ptr, secattr); +break ; +#endif /* IPv6 */ + }return -ENOMSG ; }
security/selinux/netlabel.c +6 -3
@@ -54,6 +54,7 @@* */ static int selinux_netlbl_sidlookup_cached (struct sk_buff *skb, +u16 family,struct netlbl_lsm_secattr *secattr,u32 *sid) {
@@ -63,7 +64,7 @@ static int selinux_netlbl_sidlookup_cached(struct sk_buff *skb,if (rc ==0 && (secattr->flags &NETLBL_SECATTR_CACHEABLE ) && (secattr->flags &NETLBL_SECATTR_CACHE )) -netlbl_cache_add (skb, secattr); +netlbl_cache_add (skb, family, secattr);return rc; }
@@ -214,7 +215,8 @@ int selinux_netlbl_skbuff_getsid(struct sk_buff *skb,netlbl_secattr_init (&secattr); rc =netlbl_skbuff_getattr (skb, family, &secattr);if (rc ==0 && secattr.flags !=NETLBL_SECATTR_NONE ) - rc =selinux_netlbl_sidlookup_cached (skb, &secattr, sid); + rc =selinux_netlbl_sidlookup_cached (skb, family, + &secattr, sid);else *sid =SECSID_NULL ; *type = secattr.type;
@@ -382,7 +384,8 @@ int selinux_netlbl_sock_rcv_skb(struct sk_security_struct *sksec,netlbl_secattr_init (&secattr); rc =netlbl_skbuff_getattr (skb, family, &secattr);if (rc ==0 && secattr.flags !=NETLBL_SECATTR_NONE ) - rc =selinux_netlbl_sidlookup_cached (skb, &secattr, &nlbl_sid); + rc =selinux_netlbl_sidlookup_cached (skb, family, + &secattr, &nlbl_sid);else nlbl_sid =SECINITSID_UNLABELED ;netlbl_secattr_destroy (&secattr);
Signature · 1 line
2.7.0