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
This commit is contained in:
Robert Watson 2008-10-26 22:45:18 +00:00
parent dd8ac7f990
commit 4b908c8bb4
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=184307
5 changed files with 160 additions and 5 deletions

View File

@ -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 @@ frag6_input(struct mbuf **mp, int *offp, int proto)
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 @@ frag6_input(struct mbuf **mp, int *offp, int proto)
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--;
}

View File

@ -83,6 +83,7 @@ struct ip6q {
u_char *ip6q_nxtp;
#endif
int ip6q_nfrag; /* # of fragments */
struct label *ip6q_label;
};
struct ip6asfrag {

View File

@ -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);

View File

@ -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)
{

View File

@ -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,