Thread (2 messages) flat view 2 messages, 2 authors, 2016-02-07

Re: [RFC PATCH v2 14/18] calipso: Allow the lsm to label the skbuff directly.

From: Paul Moore <hidden>
Date: 2016-02-07 19:56:17
Also in: selinux

On Friday, January 08, 2016 09:52:50 AM Huw Davies wrote:
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 <redacted>
...
quoted hunk ↗ jump to hunk
diff --git a/include/net/ipv6.h b/include/net/ipv6.h
index 5f9c252..71b5045 100644
--- a/include/net/ipv6.h
+++ b/include/net/ipv6.h
@@ -920,7 +920,7 @@ enum {
 int ipv6_find_hdr(const struct sk_buff *skb, unsigned int *offset, int
target, unsigned short *fragoff, int *fragflg);

-int ipv6_find_tlv(struct sk_buff *skb, int offset, int type);
+int ipv6_find_tlv(const struct sk_buff *skb, int offset, int type);
It probably does make sense to constify the skb argument, but you should do 
that in a separate patch.
quoted hunk ↗ jump to hunk
 struct in6_addr *fl6_update_dst(struct flowi6 *fl6,
 				const struct ipv6_txoptions *opt,
diff --git a/include/net/netlabel.h b/include/net/netlabel.h
index a2408c3..0697ba2 100644
--- a/include/net/netlabel.h
+++ b/include/net/netlabel.h
@@ -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
+ * @optptr: find option in packet
How about "skbuff_optptr" instead?
+ * @getattr: retrieve attr from memory block
How about "opt_getattr"?
+ * @skbuff_setattr: set the skbuff's attr
+ * @skbuff_delattr: remove the skbuff's attr
...
+/**
+ * calipso_skbuff_setattr - Set the CALIPSO option on a packet
+ * @skb: the packet
+ * @doi_def: the CALIPSO DOI to use
+ * @secattr: the security attributes
+ *
+ * Description:
+ * Set the CALIPSO option on the given packet based on the security
attributes. + * Returns a pointer to the IP header on success and NULL on
failure. + *
+ */
+static int calipso_skbuff_setattr(struct sk_buff *skb,
+				  const struct calipso_doi *doi_def,
+				  const struct netlbl_lsm_secattr *secattr)
+{
+	int ret_val;
+	struct ipv6hdr *ip6_hdr;
+	struct ipv6_opt_hdr *hop;
+	unsigned char buf[CALIPSO_MAX_BUFFER];
+	int len_delta;
+	unsigned int start, end, next_opt, pad;
+
+	ip6_hdr = ipv6_hdr(skb);
+	if (ip6_hdr->nexthdr == NEXTHDR_HOP) {
+		hop = (struct ipv6_opt_hdr *)(ip6_hdr + 1);
+		ret_val = calipso_opt_find(hop, &start, &end);
+		if (ret_val && ret_val != -ENOENT)
+			return ret_val;
+		if (end != ipv6_optlen(hop))
+			next_opt = end;
+		else
+			next_opt = 0;
+		len_delta = -(int)end;
+	} else {
+		start = 0;
+		next_opt = 0;
+		len_delta = 0;
+	}
+
+	memset(buf, 0, sizeof(buf));
+	ret_val = calipso_genopt(buf, start & 3, sizeof(buf), doi_def, secattr);
+	if (ret_val < 0)
+		return ret_val;
+
+	end = start + ret_val;
+
+	if (WARN_ON_ONCE(end & 3))
+		return -EINVAL;
See my earlier comments about the use of WARN_ON_ONCE().
+	pad = ((end & 7) + (next_opt & 7)) & 7;
+	len_delta += end + pad;
+
+	if (WARN_ON_ONCE(len_delta & 7))
+		return -EINVAL;
Same.
+	ret_val = skb_cow(skb, skb_headroom(skb) + len_delta);
+	if (ret_val < 0)
+		return ret_val;
+
+	if (len_delta) {
+		if (len_delta > 0)
+			skb_push(skb, len_delta);
+		else
+			skb_pull(skb, -len_delta);
+		memmove((char *)ip6_hdr - len_delta, ip6_hdr,
+			sizeof(*ip6_hdr) + start);
+		skb_reset_network_header(skb);
+		ip6_hdr = ipv6_hdr(skb);
+	}
-- 
paul moore
security @ redhat
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help