calipso: Allow the lsm to label the skbuff directly.
RFC PATCH v3 15/19 calipso: Allow the lsm to label the skbuff directly.
In some cases, the lsm needs to add the label to the skbuff directly. A NF_INET_LOCAL_OUT IPv6 hook is added to selinux to match the IPv4 behaviour. This allows selinux to label the skbuffs that it requires.
Signed-off-by Huw Davies <[email protected]>
--- include/net/netlabel.h | 11 +++ net/ipv6/calipso.c | 165 ++++++++++++++++++++++++++++++++++++++++ net/netlabel/netlabel_calipso.c | 82 ++++++++++++++++++++ net/netlabel/netlabel_calipso.h | 7 ++ net/netlabel/netlabel_kapi.c | 32 +++++++- security/selinux/hooks.c | 15 ++++ 6 files changed, 308 insertions(+), 4 deletions(-)
include/net/netlabel.h +11 -0
@@ -231,6 +231,10 @@ struct netlbl_lsm_secattr {* @sock_delattr: remove the socket's attr * @req_setattr: set the req socket's attr * @req_delattr: remove the req socket's attr +* @opt_getattr: retrieve attr from memory block +* @skbuff_optptr: find option in packet +* @skbuff_setattr: set the skbuff's attr +* @skbuff_delattr: remove the skbuff's attr * * Description: * This structure is filled out by the CALIPSO engine and passed
@@ -258,6 +262,13 @@ struct netlbl_calipso_ops {const struct calipso_doi *doi_def, const struct netlbl_lsm_secattr *secattr);void (*req_delattr)(struct request_sock *req); +int (*opt_getattr)(const unsigned char *calipso, +struct netlbl_lsm_secattr *secattr); +unsigned char *(*skbuff_optptr)(const struct sk_buff *skb); +int (*skbuff_setattr)(struct sk_buff *skb, +const struct calipso_doi *doi_def, +const struct netlbl_lsm_secattr *secattr); +int (*skbuff_delattr)(struct sk_buff *skb); };/*
net/ipv6/calipso.c +165 -0
183 lines not on this page · raw message
net/netlabel/netlabel_calipso.c +82 -0
85 lines not on this page · raw message
net/netlabel/netlabel_calipso.h +7 -0
@@ -137,5 +137,12 @@ int calipso_req_setattr(struct request_sock *req,const struct calipso_doi *doi_def, const struct netlbl_lsm_secattr *secattr);void calipso_req_delattr (struct request_sock *req); +unsigned char *calipso_optptr (const struct sk_buff *skb); +int calipso_getattr (const unsigned char *calipso, +struct netlbl_lsm_secattr *secattr); +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);#endif
net/netlabel/netlabel_kapi.c +28 -4
@@ -1148,13 +1148,17 @@ int netlbl_skbuff_setattr(struct sk_buff *skb, {int ret_val;struct iphdr *hdr4; +#if IS_ENABLED (CONFIG_IPV6 ) +struct ipv6hdr *hdr6; +#endif struct netlbl_dommap_def *entry;rcu_read_lock ();switch (family) {case AF_INET : hdr4 =ip_hdr (skb); - entry =netlbl_domhsh_getentry_af4 (secattr->domain,hdr4->daddr); + entry =netlbl_domhsh_getentry_af4 (secattr->domain, + hdr4->daddr);if (entry ==NULL ) { ret_val = -ENOENT ; goto skbuff_setattr_return;
@@ -1175,9 +1179,26 @@ int netlbl_skbuff_setattr(struct sk_buff *skb,break ;#if IS_ENABLED (CONFIG_IPV6 )case AF_INET6 : -/* since we don't support any IPv6 labeling protocols right -* now we can optimize everything away until we do */ - ret_val =0 ; + hdr6 =ipv6_hdr (skb); + entry =netlbl_domhsh_getentry_af6 (secattr->domain, + &hdr6->daddr); +if (entry ==NULL ) { + ret_val = -ENOENT ; + goto skbuff_setattr_return; + } +switch (entry->type) { +case NETLBL_NLTYPE_CALIPSO : + ret_val =calipso_skbuff_setattr (skb, entry->calipso, + secattr); +break ; +case NETLBL_NLTYPE_UNLABELED : +/* just delete the protocols we support for right now +* but we could remove other protocols if needed */ + ret_val =calipso_skbuff_delattr (skb); +break ; +default : + ret_val = -ENOENT ; + }break ;#endif /* IPv6 */ default :
@@ -1216,6 +1237,9 @@ int netlbl_skbuff_getattr(const struct sk_buff *skb,break ;#if IS_ENABLED (CONFIG_IPV6 )case AF_INET6 : + ptr =calipso_optptr (skb); +if (ptr &&calipso_getattr (ptr, secattr) ==0 ) +return 0 ;break ;#endif /* IPv6 */ }
security/selinux/hooks.c +15 -0
@@ -4997,6 +4997,15 @@ static unsigned int selinux_ipv4_output(void *priv,return selinux_ip_output (skb,PF_INET ); } +#if defined(CONFIG_IPV6 ) || defined(CONFIG_IPV6_MODULE ) +static unsigned int selinux_ipv6_output (void *priv, +struct sk_buff *skb, +const struct nf_hook_state *state) +{ +return selinux_ip_output (skb,PF_INET6 ); +} +#endif /* IPV6 */ +static unsigned int selinux_ip_postroute_compat (struct sk_buff *skb,int ifindex,u16 family)
@@ -6237,6 +6246,12 @@ static struct nf_hook_ops selinux_nf_ops[] = { .hooknum = NF_INET_FORWARD, .priority = NF_IP6_PRI_SELINUX_FIRST, }, + { + .hook = selinux_ipv6_output, + .pf = NFPROTO_IPV6, + .hooknum = NF_INET_LOCAL_OUT, + .priority = NF_IP6_PRI_SELINUX_FIRST, + },#endif /* IPV6 */ };
Signature · 1 line
2.7.0