summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrwatson <rwatson@FreeBSD.org>2008-10-26 22:45:18 +0000
committerrwatson <rwatson@FreeBSD.org>2008-10-26 22:45:18 +0000
commit0db6d4519ceacc0d9c0af2e667962f6c0546029e (patch)
tree8115762dcf638e2c7a405f526a67f7e21a803737
parent879c5460c084672911baf77e5c9d3b7094e4d2ff (diff)
downloadFreeBSD-src-0db6d4519ceacc0d9c0af2e667962f6c0546029e.zip
FreeBSD-src-0db6d4519ceacc0d9c0af2e667962f6c0546029e.tar.gz
Add a MAC label, MAC Framework, and MAC policy entry points for IPv6
fragment reassembly queues. This allows policies to label reassembly queues, perform access control checks when matching fragments to a queue, update a queue label when fragments are matched, and label the resulting reassembled datagram. Obtained from: TrustedBSD Project
-rw-r--r--sys/netinet6/frag6.c32
-rw-r--r--sys/netinet6/ip6_var.h1
-rw-r--r--sys/security/mac/mac_framework.h10
-rw-r--r--sys/security/mac/mac_inet6.c100
-rw-r--r--sys/security/mac/mac_policy.h22
5 files changed, 160 insertions, 5 deletions
diff --git a/sys/netinet6/frag6.c b/sys/netinet6/frag6.c
index fca85c5..961af87 100644
--- a/sys/netinet6/frag6.c
+++ b/sys/netinet6/frag6.c
@@ -32,6 +32,8 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
+#include "opt_mac.h"
+
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/malloc.h>
@@ -56,6 +58,8 @@ __FBSDID("$FreeBSD$");
#include <netinet/in_systm.h> /* for ECN definitions */
#include <netinet/ip.h> /* for ECN definitions */
+#include <security/mac/mac_framework.h>
+
/*
* Define it to get a correct behavior on per-interface statistics.
* You will need to perform an extra routing table lookup, per fragment,
@@ -228,7 +232,11 @@ frag6_input(struct mbuf **mp, int *offp, int proto)
for (q6 = V_ip6q.ip6q_next; q6 != &V_ip6q; q6 = q6->ip6q_next)
if (ip6f->ip6f_ident == q6->ip6q_ident &&
IN6_ARE_ADDR_EQUAL(&ip6->ip6_src, &q6->ip6q_src) &&
- IN6_ARE_ADDR_EQUAL(&ip6->ip6_dst, &q6->ip6q_dst))
+ IN6_ARE_ADDR_EQUAL(&ip6->ip6_dst, &q6->ip6q_dst)
+#ifdef MAC
+ && mac_ip6q_match(m, q6)
+#endif
+ )
break;
if (q6 == &V_ip6q) {
@@ -254,7 +262,13 @@ frag6_input(struct mbuf **mp, int *offp, int proto)
if (q6 == NULL)
goto dropfrag;
bzero(q6, sizeof(*q6));
-
+#ifdef MAC
+ if (mac_ip6q_init(q6, M_NOWAIT) != 0) {
+ free(q6, M_FTABLE);
+ goto dropfrag;
+ }
+ mac_ip6q_create(m, q6);
+#endif
frag6_insque(q6, &V_ip6q);
/* ip6q_nxt will be filled afterwards, from 1st fragment */
@@ -461,6 +475,10 @@ frag6_input(struct mbuf **mp, int *offp, int proto)
#endif
insert:
+#ifdef MAC
+ if (!first_frag)
+ mac_ip6q_update(m, q6);
+#endif
/*
* Stick new segment in its place;
@@ -533,6 +551,9 @@ insert:
if ((t = m_split(m, offset, M_DONTWAIT)) == NULL) {
frag6_remque(q6);
V_frag6_nfrags -= q6->ip6q_nfrag;
+#ifdef MAC
+ mac_ip6q_destroy(q6);
+#endif
free(q6, M_FTABLE);
V_frag6_nfragpackets--;
goto dropfrag;
@@ -551,6 +572,10 @@ insert:
frag6_remque(q6);
V_frag6_nfrags -= q6->ip6q_nfrag;
+#ifdef MAC
+ mac_ip6q_reassemble(q6, m);
+ mac_ip6q_destroy(q6);
+#endif
free(q6, M_FTABLE);
V_frag6_nfragpackets--;
@@ -623,6 +648,9 @@ frag6_freef(struct ip6q *q6)
}
frag6_remque(q6);
V_frag6_nfrags -= q6->ip6q_nfrag;
+#ifdef MAC
+ mac_ip6q_destroy(q6);
+#endif
free(q6, M_FTABLE);
V_frag6_nfragpackets--;
}
diff --git a/sys/netinet6/ip6_var.h b/sys/netinet6/ip6_var.h
index f13ea34..8f0c2c5 100644
--- a/sys/netinet6/ip6_var.h
+++ b/sys/netinet6/ip6_var.h
@@ -83,6 +83,7 @@ struct ip6q {
u_char *ip6q_nxtp;
#endif
int ip6q_nfrag; /* # of fragments */
+ struct label *ip6q_label;
};
struct ip6asfrag {
diff --git a/sys/security/mac/mac_framework.h b/sys/security/mac/mac_framework.h
index c09088b..790b921 100644
--- a/sys/security/mac/mac_framework.h
+++ b/sys/security/mac/mac_framework.h
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 1999-2002, 2007 Robert N. M. Watson
+ * Copyright (c) 1999-2002, 2007-2008 Robert N. M. Watson
* Copyright (c) 2001-2005 Networks Associates Technology, Inc.
* Copyright (c) 2005-2006 SPARTA, Inc.
* All rights reserved.
@@ -60,6 +60,7 @@ struct ifnet;
struct ifreq;
struct image_params;
struct inpcb;
+struct ip6q;
struct ipq;
struct ksem;
struct label;
@@ -138,6 +139,13 @@ void mac_inpcb_destroy(struct inpcb *);
int mac_inpcb_init(struct inpcb *, int);
void mac_inpcb_sosetlabel(struct socket *so, struct inpcb *inp);
+void mac_ip6q_create(struct mbuf *m, struct ip6q *q6);
+void mac_ip6q_destroy(struct ip6q *q6);
+int mac_ip6q_init(struct ip6q *q6, int);
+int mac_ip6q_match(struct mbuf *m, struct ip6q *q6);
+void mac_ip6q_reassemble(struct ip6q *q6, struct mbuf *m);
+void mac_ip6q_update(struct mbuf *m, struct ip6q *q6);
+
void mac_ipq_create(struct mbuf *m, struct ipq *q);
void mac_ipq_destroy(struct ipq *q);
int mac_ipq_init(struct ipq *q, int);
diff --git a/sys/security/mac/mac_inet6.c b/sys/security/mac/mac_inet6.c
index 65a93e1..068455b 100644
--- a/sys/security/mac/mac_inet6.c
+++ b/sys/security/mac/mac_inet6.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2007 Robert N. M. Watson
+ * Copyright (c) 2007-2008 Robert N. M. Watson
* All rights reserved.
*
* This software was developed by Robert Watson for the TrustedBSD Project.
@@ -49,10 +49,108 @@ __FBSDID("$FreeBSD$");
#include <net/if.h>
#include <net/if_var.h>
+#include <netinet/in.h>
+#include <netinet/ip6.h>
+#include <netinet6/ip6_var.h>
+
#include <security/mac/mac_framework.h>
#include <security/mac/mac_internal.h>
#include <security/mac/mac_policy.h>
+static struct label *
+mac_ip6q_label_alloc(int flag)
+{
+ struct label *label;
+ int error;
+
+ label = mac_labelzone_alloc(flag);
+ if (label == NULL)
+ return (NULL);
+
+ MAC_CHECK(ip6q_init_label, label, flag);
+ if (error) {
+ MAC_PERFORM(ip6q_destroy_label, label);
+ mac_labelzone_free(label);
+ return (NULL);
+ }
+ return (label);
+}
+
+int
+mac_ip6q_init(struct ip6q *q6, int flag)
+{
+
+ if (mac_labeled & MPC_OBJECT_IPQ) {
+ q6->ip6q_label = mac_ip6q_label_alloc(flag);
+ if (q6->ip6q_label == NULL)
+ return (ENOMEM);
+ } else
+ q6->ip6q_label = NULL;
+ return (0);
+}
+
+static void
+mac_ip6q_label_free(struct label *label)
+{
+
+ MAC_PERFORM(ip6q_destroy_label, label);
+ mac_labelzone_free(label);
+}
+
+void
+mac_ip6q_destroy(struct ip6q *q6)
+{
+
+ if (q6->ip6q_label != NULL) {
+ mac_ip6q_label_free(q6->ip6q_label);
+ q6->ip6q_label = NULL;
+ }
+}
+
+void
+mac_ip6q_reassemble(struct ip6q *q6, struct mbuf *m)
+{
+ struct label *label;
+
+ label = mac_mbuf_to_label(m);
+
+ MAC_PERFORM(ip6q_reassemble, q6, q6->ip6q_label, m, label);
+}
+
+void
+mac_ip6q_create(struct mbuf *m, struct ip6q *q6)
+{
+ struct label *label;
+
+ label = mac_mbuf_to_label(m);
+
+ MAC_PERFORM(ip6q_create, m, label, q6, q6->ip6q_label);
+}
+
+int
+mac_ip6q_match(struct mbuf *m, struct ip6q *q6)
+{
+ struct label *label;
+ int result;
+
+ label = mac_mbuf_to_label(m);
+
+ result = 1;
+ MAC_BOOLEAN(ip6q_match, &&, m, label, q6, q6->ip6q_label);
+
+ return (result);
+}
+
+void
+mac_ip6q_update(struct mbuf *m, struct ip6q *q6)
+{
+ struct label *label;
+
+ label = mac_mbuf_to_label(m);
+
+ MAC_PERFORM(ip6q_update, m, label, q6, q6->ip6q_label);
+}
+
void
mac_netinet6_nd6_send(struct ifnet *ifp, struct mbuf *m)
{
diff --git a/sys/security/mac/mac_policy.h b/sys/security/mac/mac_policy.h
index 63ba829..8a2f9f2 100644
--- a/sys/security/mac/mac_policy.h
+++ b/sys/security/mac/mac_policy.h
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 1999-2002, 2007 Robert N. M. Watson
+ * Copyright (c) 1999-2002, 2007-2008 Robert N. M. Watson
* Copyright (c) 2001-2005 Networks Associates Technology, Inc.
* Copyright (c) 2005-2006 SPARTA, Inc.
* Copyright (c) 2008 Apple Inc.
@@ -72,6 +72,7 @@ struct devfs_dirent;
struct ifnet;
struct image_params;
struct inpcb;
+struct ip6q;
struct ipq;
struct ksem;
struct label;
@@ -201,6 +202,17 @@ typedef void (*mpo_inpcb_sosetlabel_t)(struct socket *so,
struct label *label, struct inpcb *inp,
struct label *inplabel);
+typedef void (*mpo_ip6q_create_t)(struct mbuf *m, struct label *mlabel,
+ struct ip6q *q6, struct label *q6label);
+typedef void (*mpo_ip6q_destroy_label_t)(struct label *label);
+typedef int (*mpo_ip6q_init_label_t)(struct label *label, int flag);
+typedef int (*mpo_ip6q_match_t)(struct mbuf *m, struct label *mlabel,
+ struct ip6q *q6, struct label *q6label);
+typedef void (*mpo_ip6q_reassemble)(struct ip6q *q6, struct label *q6label,
+ struct mbuf *m, struct label *mlabel);
+typedef void (*mpo_ip6q_update_t)(struct mbuf *m, struct label *mlabel,
+ struct ip6q *q6, struct label *q6label);
+
typedef void (*mpo_ipq_create_t)(struct mbuf *m, struct label *mlabel,
struct ipq *q, struct label *qlabel);
typedef void (*mpo_ipq_destroy_label_t)(struct label *label);
@@ -698,6 +710,13 @@ struct mac_policy_ops {
mpo_inpcb_init_label_t mpo_inpcb_init_label;
mpo_inpcb_sosetlabel_t mpo_inpcb_sosetlabel;
+ mpo_ip6q_create_t mpo_ip6q_create;
+ mpo_ip6q_destroy_label_t mpo_ip6q_destroy_label;
+ mpo_ip6q_init_label_t mpo_ip6q_init_label;
+ mpo_ip6q_match_t mpo_ip6q_match;
+ mpo_ip6q_reassemble mpo_ip6q_reassemble;
+ mpo_ip6q_update_t mpo_ip6q_update;
+
mpo_ipq_create_t mpo_ipq_create;
mpo_ipq_destroy_label_t mpo_ipq_destroy_label;
mpo_ipq_init_label_t mpo_ipq_init_label;
@@ -970,6 +989,7 @@ struct mac_policy_conf {
#define MPC_OBJECT_SYSVSEM 0x0000000000010000
#define MPC_OBJECT_SYSVSHM 0x0000000000020000
#define MPC_OBJECT_SYNCACHE 0x0000000000040000
+#define MPC_OBJECT_IP6Q 0x0000000000080000
/*-
* The TrustedBSD MAC Framework has a major version number, MAC_VERSION,
OpenPOWER on IntegriCloud