[PATCH 1/1]: ipsec audit

Joy Latten latten at austin.ibm.com
Fri Oct 27 00:23:18 UTC 2006


This code adds auditing to IPSec. An audit message gets logged whenever
an ipsec policy or security association is added or deleted from the
kernel's Security Policy Database and/or Security Association Database.

IPSec policies and SAs can be added  and/or deleted via the pfkey api or
the netlink api, which was extended to accomodate key management.
PFKEYv2 is a socket protocol for key management defined in RFC 2367.
I added auditing for both key management protocols. Both protocols
utilize the same code in some places. 

Please let me know if this patch is acceptable.

Regards,
Joy Latten

---------------------------------------------------------------------------------

diff -urpN linux-2.6.18.ppc64/include/linux/audit.h
linux-2.6.18.ppc64.patch/include/linux/audit.h
--- linux-2.6.18.ppc64/include/linux/audit.h	2006-10-26
03:10:10.000000000 -0500
+++ linux-2.6.18.ppc64.patch/include/linux/audit.h	2006-10-26
07:04:08.000000000 -0500
@@ -100,6 +100,10 @@
 #define AUDIT_MAC_CIPSOV4_DEL	1408	/* NetLabel: del CIPSOv4 DOI entry
*/
 #define AUDIT_MAC_MAP_ADD	1409	/* NetLabel: add LSM domain mapping */
 #define AUDIT_MAC_MAP_DEL	1410	/* NetLabel: del LSM domain mapping */
+#define AUDIT_MAC_IPSEC_ADDSA   1411	/* Add a XFRM state */
+#define AUDIT_MAC_IPSEC_DELSA   1412	/* Delete a XFRM state */ 
+#define AUDIT_MAC_IPSEC_ADDSPD  1413	/* Add a XFRM policy */
+#define AUDIT_MAC_IPSEC_DELSPD  1414	/* Delete a XFRM policy */
 
 #define AUDIT_FIRST_KERN_ANOM_MSG   1700
 #define AUDIT_LAST_KERN_ANOM_MSG    1799
diff -urpN linux-2.6.18.ppc64/include/net/xfrm.h
linux-2.6.18.ppc64.patch/include/net/xfrm.h
--- linux-2.6.18.ppc64/include/net/xfrm.h	2006-10-26 03:10:11.000000000
-0500
+++ linux-2.6.18.ppc64.patch/include/net/xfrm.h	2006-10-26
07:04:08.000000000 -0500
@@ -18,6 +18,7 @@
 #include <net/route.h>
 #include <net/ipv6.h>
 #include <net/ip6_fib.h>
+#include <linux/audit.h>
 
 #define XFRM_ALIGN8(len)	(((len) + 7) & ~7)
 #define MODULE_ALIAS_XFRM_MODE(family, encap) \
@@ -231,7 +232,7 @@ extern void km_state_notify(struct xfrm_
 struct xfrm_tmpl;
 extern int km_query(struct xfrm_state *x, struct xfrm_tmpl *t, struct
xfrm_policy *pol);
 extern void km_state_expired(struct xfrm_state *x, int hard, u32 pid);
-extern int __xfrm_state_delete(struct xfrm_state *x);
+extern int __xfrm_state_delete(struct xfrm_state *x, uid_t auid);
 
 struct xfrm_state_afinfo {
 	unsigned short		family;
@@ -737,16 +738,17 @@ static inline int xfrm_sk_clone_policy(s
 	return 0;
 }
 
-extern int xfrm_policy_delete(struct xfrm_policy *pol, int dir);
+extern int xfrm_policy_delete(struct xfrm_policy *pol, int dir, uid_t
auid);
 
 static inline void xfrm_sk_free_policy(struct sock *sk)
 {
+	uid_t auid = audit_get_loginuid(current->audit_context);
 	if (unlikely(sk->sk_policy[0] != NULL)) {
-		xfrm_policy_delete(sk->sk_policy[0], XFRM_POLICY_MAX);
+		xfrm_policy_delete(sk->sk_policy[0], XFRM_POLICY_MAX, auid);
 		sk->sk_policy[0] = NULL;
 	}
 	if (unlikely(sk->sk_policy[1] != NULL)) {
-		xfrm_policy_delete(sk->sk_policy[1], XFRM_POLICY_MAX+1);
+		xfrm_policy_delete(sk->sk_policy[1], XFRM_POLICY_MAX+1, auid);
 		sk->sk_policy[1] = NULL;
 	}
 }
@@ -898,13 +900,13 @@ extern struct xfrm_state *xfrm_state_fin
 					  struct xfrm_policy *pol, int *err,
 					  unsigned short family);
 extern int xfrm_state_check_expire(struct xfrm_state *x);
-extern void xfrm_state_insert(struct xfrm_state *x);
-extern int xfrm_state_add(struct xfrm_state *x);
-extern int xfrm_state_update(struct xfrm_state *x);
+extern void xfrm_state_insert(struct xfrm_state *x, uid_t auid);
+extern int xfrm_state_add(struct xfrm_state *x, uid_t auid);
+extern int xfrm_state_update(struct xfrm_state *x, uid_t auid);
 extern struct xfrm_state *xfrm_state_lookup(xfrm_address_t *daddr, u32
spi, u8 proto, unsigned short family);
 extern struct xfrm_state *xfrm_find_acq_byseq(u32 seq);
-extern int xfrm_state_delete(struct xfrm_state *x);
-extern void xfrm_state_flush(u8 proto);
+extern int xfrm_state_delete(struct xfrm_state *x, uid_t auid);
+extern void xfrm_state_flush(u8 proto, uid_t auid);
 extern int xfrm_replay_check(struct xfrm_state *x, u32 seq);
 extern void xfrm_replay_advance(struct xfrm_state *x, u32 seq);
 extern void xfrm_replay_notify(struct xfrm_state *x, int event);
@@ -948,17 +950,18 @@ static inline int xfrm_dst_lookup(struct
 
 struct xfrm_policy *xfrm_policy_alloc(gfp_t gfp);
 extern int xfrm_policy_walk(int (*func)(struct xfrm_policy *, int, int,
void*), void *);
-int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl);
+int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl,
uid_t auid);
 struct xfrm_policy *xfrm_policy_bysel_ctx(int dir, struct xfrm_selector
*sel,
-					  struct xfrm_sec_ctx *ctx, int delete);
-struct xfrm_policy *xfrm_policy_byid(int dir, u32 id, int delete);
-void xfrm_policy_flush(void);
+					  struct xfrm_sec_ctx *ctx, int delete,
+					  uid_t auid);
+struct xfrm_policy *xfrm_policy_byid(int dir, u32 id, int delete, uid_t
auid);
+void xfrm_policy_flush(uid_t auid);
 u32 xfrm_get_acqseq(void);
 void xfrm_alloc_spi(struct xfrm_state *x, u32 minspi, u32 maxspi);
 struct xfrm_state * xfrm_find_acq(u8 mode, u32 reqid, u8 proto, 
 				  xfrm_address_t *daddr, xfrm_address_t *saddr, 
 				  int create, unsigned short family);
-extern void xfrm_policy_flush(void);
+extern void xfrm_policy_flush(uid_t auid);
 extern int xfrm_sk_policy_insert(struct sock *sk, int dir, struct
xfrm_policy *pol);
 extern int xfrm_flush_bundles(void);
 extern void xfrm_flush_all_bundles(void);
diff -urpN linux-2.6.18.ppc64/kernel/auditsc.c
linux-2.6.18.ppc64.patch/kernel/auditsc.c
--- linux-2.6.18.ppc64/kernel/auditsc.c	2006-10-26 03:10:35.000000000
-0500
+++ linux-2.6.18.ppc64.patch/kernel/auditsc.c	2006-10-26
07:04:49.000000000 -0500
@@ -1488,6 +1488,7 @@ uid_t audit_get_loginuid(struct audit_co
 {
 	return ctx ? ctx->loginuid : -1;
 }
+EXPORT_SYMBOL(audit_get_loginuid);
 
 /**
  * __audit_mq_open - record audit data for a POSIX MQ open
diff -urpN linux-2.6.18.ppc64/net/ipv4/ipcomp.c
linux-2.6.18.ppc64.patch/net/ipv4/ipcomp.c
--- linux-2.6.18.ppc64/net/ipv4/ipcomp.c	2006-09-19 22:42:06.000000000
-0500
+++ linux-2.6.18.ppc64.patch/net/ipv4/ipcomp.c	2006-10-26
07:04:08.000000000 -0500
@@ -29,6 +29,7 @@
 #include <net/icmp.h>
 #include <net/ipcomp.h>
 #include <net/protocol.h>
+#include <linux/audit.h>
 
 struct ipcomp_tfms {
 	struct list_head list;
@@ -251,7 +252,7 @@ static int ipcomp_tunnel_attach(struct x
 			err = -EINVAL;
 			goto out;
 		}
-		xfrm_state_insert(t);
+		xfrm_state_insert(t,audit_get_loginuid(current->audit_context));
 		xfrm_state_hold(t);
 	}
 	x->tunnel = t;
diff -urpN linux-2.6.18.ppc64/net/ipv6/ipcomp6.c
linux-2.6.18.ppc64.patch/net/ipv6/ipcomp6.c
--- linux-2.6.18.ppc64/net/ipv6/ipcomp6.c	2006-09-19 22:42:06.000000000
-0500
+++ linux-2.6.18.ppc64.patch/net/ipv6/ipcomp6.c	2006-10-26
07:04:08.000000000 -0500
@@ -50,6 +50,7 @@
 #include <linux/ipv6.h>
 #include <linux/icmpv6.h>
 #include <linux/mutex.h>
+#include <linux/audit.h>
 
 struct ipcomp6_tfms {
 	struct list_head list;
@@ -246,7 +247,7 @@ static int ipcomp6_tunnel_attach(struct 
 			err = -EINVAL;
 			goto out;
 		}
-		xfrm_state_insert(t);
+		xfrm_state_insert(t,audit_get_loginuid(current->audit_context));
 		xfrm_state_hold(t);
 	}
 	x->tunnel = t;
diff -urpN linux-2.6.18.ppc64/net/key/af_key.c
linux-2.6.18.ppc64.patch/net/key/af_key.c
--- linux-2.6.18.ppc64/net/key/af_key.c	2006-10-26 03:10:11.000000000
-0500
+++ linux-2.6.18.ppc64.patch/net/key/af_key.c	2006-10-26
07:04:08.000000000 -0500
@@ -29,6 +29,7 @@
 #include <net/xfrm.h>
 
 #include <net/sock.h>
+#include <linux/audit.h>
 
 #define _X2KEY(x) ((x) == XFRM_INF ? 0 : (x))
 #define _KEY2X(x) ((x) == 0 ? XFRM_INF : (x))
@@ -1416,9 +1417,9 @@ static int pfkey_add(struct sock *sk, st
 
 	xfrm_state_hold(x);
 	if (hdr->sadb_msg_type == SADB_ADD)
-		err = xfrm_state_add(x);
+		err = xfrm_state_add(x, audit_get_loginuid(current->audit_context));
 	else
-		err = xfrm_state_update(x);
+		err = xfrm_state_update(x,
audit_get_loginuid(current->audit_context));
 
 	if (err < 0) {
 		x->km.state = XFRM_STATE_DEAD;
@@ -1461,7 +1462,7 @@ static int pfkey_delete(struct sock *sk,
 		goto out;
 	}
 	
-	err = xfrm_state_delete(x);
+	err = xfrm_state_delete(x,
audit_get_loginuid(current->audit_context));
 	if (err < 0)
 		goto out;
 
@@ -1642,7 +1643,7 @@ static int pfkey_flush(struct sock *sk, 
 	if (proto == 0)
 		return -EINVAL;
 
-	xfrm_state_flush(proto);
+	xfrm_state_flush(proto, audit_get_loginuid(current->audit_context));
 	c.data.proto = proto;
 	c.seq = hdr->sadb_msg_seq;
 	c.pid = hdr->sadb_msg_pid;
@@ -2192,7 +2193,8 @@ static int pfkey_spdadd(struct sock *sk,
 		goto out;
 
 	err = xfrm_policy_insert(pol->sadb_x_policy_dir-1, xp,
-				 hdr->sadb_msg_type != SADB_X_SPDUPDATE);
+				 hdr->sadb_msg_type != SADB_X_SPDUPDATE,
+				 audit_get_loginuid(current->audit_context));
 
 	if (err)
 		goto out;
@@ -2268,7 +2270,7 @@ static int pfkey_spddelete(struct sock *
 			return err;
 	}
 
-	xp = xfrm_policy_bysel_ctx(pol->sadb_x_policy_dir-1, &sel,
tmp.security, 1);
+	xp = xfrm_policy_bysel_ctx(pol->sadb_x_policy_dir-1, &sel,
tmp.security, 1, audit_get_loginuid(current->audit_context));
 	security_xfrm_policy_free(&tmp);
 	if (xp == NULL)
 		return -ENOENT;
@@ -2331,7 +2333,8 @@ static int pfkey_spdget(struct sock *sk,
 		return -EINVAL;
 
 	xp = xfrm_policy_byid(dir, pol->sadb_x_policy_id,
-			      hdr->sadb_msg_type == SADB_X_SPDDELETE2);
+			      hdr->sadb_msg_type == SADB_X_SPDDELETE2,
+			      audit_get_loginuid(current->audit_context));
 	if (xp == NULL)
 		return -ENOENT;
 
@@ -2405,7 +2408,7 @@ static int pfkey_spdflush(struct sock *s
 {
 	struct km_event c;
 
-	xfrm_policy_flush();
+	xfrm_policy_flush(audit_get_loginuid(current->audit_context));
 	c.event = XFRM_MSG_FLUSHPOLICY;
 	c.pid = hdr->sadb_msg_pid;
 	c.seq = hdr->sadb_msg_seq;
diff -urpN linux-2.6.18.ppc64/net/xfrm/xfrm_policy.c
linux-2.6.18.ppc64.patch/net/xfrm/xfrm_policy.c
--- linux-2.6.18.ppc64/net/xfrm/xfrm_policy.c	2006-10-26
03:10:11.000000000 -0500
+++ linux-2.6.18.ppc64.patch/net/xfrm/xfrm_policy.c	2006-10-26
07:04:08.000000000 -0500
@@ -293,7 +293,7 @@ out:
 
 expired:
 	read_unlock(&xp->lock);
-	if (!xfrm_policy_delete(xp, dir))
+	if (!xfrm_policy_delete(xp, dir,
audit_get_loginuid(current->audit_context)))
 		km_policy_expired(xp, dir, 1, 0);
 	xfrm_pol_put(xp);
 }
@@ -374,13 +374,21 @@ static void xfrm_policy_gc_task(void *da
  * entry dead. The rule must be unlinked from lists to the moment.
  */
 
-static void xfrm_policy_kill(struct xfrm_policy *policy)
+static void xfrm_policy_kill(struct xfrm_policy *policy, uid_t auid)
 {
 	int dead;
 
 	write_lock_bh(&policy->lock);
 	dead = policy->dead;
 	policy->dead = 1;
+
+	if (policy->security)
+		audit_log(current->audit_context, GFP_ATOMIC,
+			  AUDIT_MAC_IPSEC_DELSPD,
+			  "spd delete: auid=%u ctx_alg=%d ctx_doi=%d ctx=%s",
+			  auid, policy->security->ctx_alg,
+			  policy->security->ctx_doi, policy->security->ctx_str);
+
 	write_unlock_bh(&policy->lock);
 
 	if (unlikely(dead)) {
@@ -417,7 +425,7 @@ static u32 xfrm_gen_index(int dir)
 	}
 }
 
-int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl)
+int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl,
uid_t auid)
 {
 	struct xfrm_policy *pol, **p;
 	struct xfrm_policy *delpol = NULL;
@@ -460,10 +468,18 @@ int xfrm_policy_insert(int dir, struct x
 	write_unlock_bh(&xfrm_policy_lock);
 
 	if (delpol)
-		xfrm_policy_kill(delpol);
+		xfrm_policy_kill(delpol, auid);
 
 	read_lock_bh(&xfrm_policy_lock);
 	gc_list = NULL;
+
+	if (policy->security)
+		audit_log(current->audit_context, GFP_ATOMIC,
+			  AUDIT_MAC_IPSEC_ADDSPD,
+			  "spd add: auid=%u ctx_alg=%d ctx_doi=%d ctx=%s",
+			  auid, policy->security->ctx_alg,
+			  policy->security->ctx_doi, policy->security->ctx_str);
+
 	for (policy = policy->next; policy; policy = policy->next) {
 		struct dst_entry *dst;
 
@@ -480,6 +496,7 @@ int xfrm_policy_insert(int dir, struct x
 		}
 		write_unlock(&policy->lock);
 	}
+
 	read_unlock_bh(&xfrm_policy_lock);
 
 	while (gc_list) {
@@ -494,7 +511,8 @@ int xfrm_policy_insert(int dir, struct x
 EXPORT_SYMBOL(xfrm_policy_insert);
 
 struct xfrm_policy *xfrm_policy_bysel_ctx(int dir, struct xfrm_selector
*sel,
-					  struct xfrm_sec_ctx *ctx, int delete)
+					  struct xfrm_sec_ctx *ctx, int delete,
+					  uid_t auid)
 {
 	struct xfrm_policy *pol, **p;
 
@@ -512,13 +530,13 @@ struct xfrm_policy *xfrm_policy_bysel_ct
 
 	if (pol && delete) {
 		atomic_inc(&flow_cache_genid);
-		xfrm_policy_kill(pol);
+		xfrm_policy_kill(pol, auid);
 	}
 	return pol;
 }
 EXPORT_SYMBOL(xfrm_policy_bysel_ctx);
 
-struct xfrm_policy *xfrm_policy_byid(int dir, u32 id, int delete)
+struct xfrm_policy *xfrm_policy_byid(int dir, u32 id, int delete, uid_t
auid)
 {
 	struct xfrm_policy *pol, **p;
 
@@ -535,13 +553,13 @@ struct xfrm_policy *xfrm_policy_byid(int
 
 	if (pol && delete) {
 		atomic_inc(&flow_cache_genid);
-		xfrm_policy_kill(pol);
+		xfrm_policy_kill(pol, auid);
 	}
 	return pol;
 }
 EXPORT_SYMBOL(xfrm_policy_byid);
 
-void xfrm_policy_flush(void)
+void xfrm_policy_flush(uid_t auid)
 {
 	struct xfrm_policy *xp;
 	int dir;
@@ -552,7 +570,7 @@ void xfrm_policy_flush(void)
 			xfrm_policy_list[dir] = xp->next;
 			write_unlock_bh(&xfrm_policy_lock);
 
-			xfrm_policy_kill(xp);
+			xfrm_policy_kill(xp, auid);
 
 			write_lock_bh(&xfrm_policy_lock);
 		}
@@ -696,7 +714,7 @@ static struct xfrm_policy *__xfrm_policy
 	return NULL;
 }
 
-int xfrm_policy_delete(struct xfrm_policy *pol, int dir)
+int xfrm_policy_delete(struct xfrm_policy *pol, int dir, uid_t auid)
 {
 	write_lock_bh(&xfrm_policy_lock);
 	pol = __xfrm_policy_unlink(pol, dir);
@@ -704,7 +722,7 @@ int xfrm_policy_delete(struct xfrm_polic
 	if (pol) {
 		if (dir < XFRM_POLICY_MAX)
 			atomic_inc(&flow_cache_genid);
-		xfrm_policy_kill(pol);
+		xfrm_policy_kill(pol, auid);
 		return 0;
 	}
 	return -ENOENT;
@@ -728,7 +746,7 @@ int xfrm_sk_policy_insert(struct sock *s
 	write_unlock_bh(&xfrm_policy_lock);
 
 	if (old_pol) {
-		xfrm_policy_kill(old_pol);
+		xfrm_policy_kill(old_pol,
audit_get_loginuid(current->audit_context));
 	}
 	return 0;
 }
diff -urpN linux-2.6.18.ppc64/net/xfrm/xfrm_state.c
linux-2.6.18.ppc64.patch/net/xfrm/xfrm_state.c
--- linux-2.6.18.ppc64/net/xfrm/xfrm_state.c	2006-10-26
03:10:09.000000000 -0500
+++ linux-2.6.18.ppc64.patch/net/xfrm/xfrm_state.c	2006-10-26
07:04:08.000000000 -0500
@@ -59,7 +59,7 @@ static DEFINE_SPINLOCK(xfrm_state_gc_loc
 
 static int xfrm_state_gc_flush_bundles;
 
-int __xfrm_state_delete(struct xfrm_state *x);
+int __xfrm_state_delete(struct xfrm_state *x, uid_t auid);
 
 static struct xfrm_state_afinfo *xfrm_state_get_afinfo(unsigned short
family);
 static void xfrm_state_put_afinfo(struct xfrm_state_afinfo *afinfo);
@@ -180,7 +180,8 @@ expired:
 		next = 2;
 		goto resched;
 	}
-	if (!__xfrm_state_delete(x) && x->id.spi)
+	if (!__xfrm_state_delete(x,
audit_get_loginuid(current->audit_context)) 
+	    && x->id.spi)
 		km_state_expired(x, 1, 0);
 
 out:
@@ -231,7 +232,7 @@ void __xfrm_state_destroy(struct xfrm_st
 }
 EXPORT_SYMBOL(__xfrm_state_destroy);
 
-int __xfrm_state_delete(struct xfrm_state *x)
+int __xfrm_state_delete(struct xfrm_state *x, uid_t auid)
 {
 	int err = -ESRCH;
 
@@ -244,6 +245,13 @@ int __xfrm_state_delete(struct xfrm_stat
 			list_del(&x->byspi);
 			__xfrm_state_put(x);
 		}
+		if (x->security)
+			audit_log(current->audit_context, GFP_ATOMIC,
+				  AUDIT_MAC_IPSEC_ADDSA,
+				  "SAD delete: auid=%u ctx_alg=%d ctx_doi=%d ctx=%s",
+				  auid, x->security->ctx_alg, 
+				  x->security->ctx_doi, x->security->ctx_str);
+
 		spin_unlock(&xfrm_state_lock);
 		if (del_timer(&x->timer))
 			__xfrm_state_put(x);
@@ -272,19 +280,19 @@ int __xfrm_state_delete(struct xfrm_stat
 }
 EXPORT_SYMBOL(__xfrm_state_delete);
 
-int xfrm_state_delete(struct xfrm_state *x)
+int xfrm_state_delete(struct xfrm_state *x, uid_t auid)
 {
 	int err;
 
 	spin_lock_bh(&x->lock);
-	err = __xfrm_state_delete(x);
+	err = __xfrm_state_delete(x, auid);
 	spin_unlock_bh(&x->lock);
 
 	return err;
 }
 EXPORT_SYMBOL(xfrm_state_delete);
 
-void xfrm_state_flush(u8 proto)
+void xfrm_state_flush(u8 proto, uid_t auid)
 {
 	int i;
 	struct xfrm_state *x;
@@ -298,7 +306,7 @@ restart:
 				xfrm_state_hold(x);
 				spin_unlock_bh(&xfrm_state_lock);
 
-				xfrm_state_delete(x);
+				xfrm_state_delete(x, auid);
 				xfrm_state_put(x);
 
 				spin_lock_bh(&xfrm_state_lock);
@@ -441,7 +449,7 @@ out:
 	return x;
 }
 
-static void __xfrm_state_insert(struct xfrm_state *x)
+static void __xfrm_state_insert(struct xfrm_state *x, uid_t auid)
 {
 	unsigned h = xfrm_dst_hash(&x->id.daddr, x->props.family);
 
@@ -461,12 +469,20 @@ static void __xfrm_state_insert(struct x
 		xfrm_state_hold(x);
 
 	wake_up(&km_waitq);
+
+	if (x->security)
+		audit_log(current->audit_context, GFP_ATOMIC,
+			  AUDIT_MAC_IPSEC_ADDSA,
+			  "SAD add: auid=%u ctx_alg=%d ctx_doi=%d, ctx=%s",
+			  auid, x->security->ctx_alg, x->security->ctx_doi,
+			  x->security->ctx_str);
+
 }
 
-void xfrm_state_insert(struct xfrm_state *x)
+void xfrm_state_insert(struct xfrm_state *x, uid_t auid)
 {
 	spin_lock_bh(&xfrm_state_lock);
-	__xfrm_state_insert(x);
+	__xfrm_state_insert(x, auid);
 	spin_unlock_bh(&xfrm_state_lock);
 
 	xfrm_flush_all_bundles();
@@ -475,7 +491,7 @@ EXPORT_SYMBOL(xfrm_state_insert);
 
 static struct xfrm_state *__xfrm_find_acq_byseq(u32 seq);
 
-int xfrm_state_add(struct xfrm_state *x)
+int xfrm_state_add(struct xfrm_state *x, uid_t auid)
 {
 	struct xfrm_state_afinfo *afinfo;
 	struct xfrm_state *x1;
@@ -510,7 +526,7 @@ int xfrm_state_add(struct xfrm_state *x)
 			x->props.mode, x->props.reqid, x->id.proto,
 			&x->id.daddr, &x->props.saddr, 0);
 
-	__xfrm_state_insert(x);
+	__xfrm_state_insert(x, auid);
 	err = 0;
 
 out:
@@ -521,7 +537,7 @@ out:
 		xfrm_flush_all_bundles();
 
 	if (x1) {
-		xfrm_state_delete(x1);
+		xfrm_state_delete(x1, auid);
 		xfrm_state_put(x1);
 	}
 
@@ -529,7 +545,7 @@ out:
 }
 EXPORT_SYMBOL(xfrm_state_add);
 
-int xfrm_state_update(struct xfrm_state *x)
+int xfrm_state_update(struct xfrm_state *x, uid_t auid)
 {
 	struct xfrm_state_afinfo *afinfo;
 	struct xfrm_state *x1;
@@ -553,7 +569,7 @@ int xfrm_state_update(struct xfrm_state 
 	}
 
 	if (x1->km.state == XFRM_STATE_ACQ) {
-		__xfrm_state_insert(x);
+		__xfrm_state_insert(x, auid);
 		x = NULL;
 	}
 	err = 0;
@@ -566,7 +582,7 @@ out:
 		return err;
 
 	if (!x) {
-		xfrm_state_delete(x1);
+		xfrm_state_delete(x1, auid);
 		xfrm_state_put(x1);
 		return 0;
 	}
@@ -1125,11 +1141,15 @@ static void xfrm_state_put_afinfo(struct
 /* Temporarily located here until net/xfrm/xfrm_tunnel.c is created */
 void xfrm_state_delete_tunnel(struct xfrm_state *x)
 {
+	uid_t auid;
+
+	auid = audit_get_loginuid(current->audit_context);
+
 	if (x->tunnel) {
 		struct xfrm_state *t = x->tunnel;
 
 		if (atomic_read(&t->tunnel_users) == 2)
-			xfrm_state_delete(t);
+			xfrm_state_delete(t, auid);
 		atomic_dec(&t->tunnel_users);
 		xfrm_state_put(t);
 		x->tunnel = NULL;
diff -urpN linux-2.6.18.ppc64/net/xfrm/xfrm_user.c
linux-2.6.18.ppc64.patch/net/xfrm/xfrm_user.c
--- linux-2.6.18.ppc64/net/xfrm/xfrm_user.c	2006-10-26
03:10:11.000000000 -0500
+++ linux-2.6.18.ppc64.patch/net/xfrm/xfrm_user.c	2006-10-26
07:04:08.000000000 -0500
@@ -27,6 +27,7 @@
 #include <net/xfrm.h>
 #include <net/netlink.h>
 #include <asm/uaccess.h>
+#include <linux/audit.h>
 
 static int verify_one_alg(struct rtattr **xfrma, enum xfrm_attr_type_t
type)
 {
@@ -396,9 +397,9 @@ static int xfrm_add_sa(struct sk_buff *s
 
 	xfrm_state_hold(x);
 	if (nlh->nlmsg_type == XFRM_MSG_NEWSA)
-		err = xfrm_state_add(x);
+		err = xfrm_state_add(x, NETLINK_CB(skb).loginuid);
 	else
-		err = xfrm_state_update(x);
+		err = xfrm_state_update(x, NETLINK_CB(skb).loginuid);
 
 	if (err < 0) {
 		x->km.state = XFRM_STATE_DEAD;
@@ -435,7 +436,7 @@ static int xfrm_del_sa(struct sk_buff *s
 		goto out;
 	}
 
-	err = xfrm_state_delete(x);
+	err = xfrm_state_delete(x, NETLINK_CB(skb).loginuid);
 	if (err < 0)
 		goto out;
 
@@ -859,7 +860,7 @@ static int xfrm_add_policy(struct sk_buf
 	 * in netlink excl is a flag and you wouldnt need
 	 * a type XFRM_MSG_UPDPOLICY - JHS */
 	excl = nlh->nlmsg_type == XFRM_MSG_NEWPOLICY;
-	err = xfrm_policy_insert(p->dir, xp, excl);
+	err = xfrm_policy_insert(p->dir, xp, excl, NETLINK_CB(skb).loginuid);
 	if (err) {
 		security_xfrm_policy_free(xp);
 		kfree(xp);
@@ -1026,6 +1027,7 @@ static int xfrm_get_policy(struct sk_buf
 	int err;
 	struct km_event c;
 	int delete;
+	uid_t auid;
 
 	p = NLMSG_DATA(nlh);
 	delete = nlh->nlmsg_type == XFRM_MSG_DELPOLICY;
@@ -1034,8 +1036,9 @@ static int xfrm_get_policy(struct sk_buf
 	if (err)
 		return err;
 
+	auid = NETLINK_CB(skb).loginuid;
 	if (p->index)
-		xp = xfrm_policy_byid(p->dir, p->index, delete);
+		xp = xfrm_policy_byid(p->dir, p->index, delete, auid);
 	else {
 		struct rtattr **rtattrs = (struct rtattr **)xfrma;
 		struct rtattr *rt = rtattrs[XFRMA_SEC_CTX-1];
@@ -1052,7 +1055,7 @@ static int xfrm_get_policy(struct sk_buf
 			if ((err = security_xfrm_policy_alloc(&tmp, uctx)))
 				return err;
 		}
-		xp = xfrm_policy_bysel_ctx(p->dir, &p->sel, tmp.security, delete);
+		xp = xfrm_policy_bysel_ctx(p->dir, &p->sel, tmp.security, delete,
auid);
 		security_xfrm_policy_free(&tmp);
 	}
 	if (xp == NULL)
@@ -1090,7 +1093,7 @@ static int xfrm_flush_sa(struct sk_buff 
 	struct km_event c;
 	struct xfrm_usersa_flush *p = NLMSG_DATA(nlh);
 
-	xfrm_state_flush(p->proto);
+	xfrm_state_flush(p->proto, NETLINK_CB(skb).loginuid);
 	c.data.proto = p->proto;
 	c.event = nlh->nlmsg_type;
 	c.seq = nlh->nlmsg_seq;
@@ -1237,7 +1240,7 @@ static int xfrm_flush_policy(struct sk_b
 {
 struct km_event c;
 
-	xfrm_policy_flush();
+	xfrm_policy_flush(NETLINK_CB(skb).loginuid);
 	c.event = nlh->nlmsg_type;
 	c.seq = nlh->nlmsg_seq;
 	c.pid = nlh->nlmsg_pid;
@@ -1251,9 +1254,12 @@ static int xfrm_add_pol_expire(struct sk
 	struct xfrm_user_polexpire *up = NLMSG_DATA(nlh);
 	struct xfrm_userpolicy_info *p = &up->pol;
 	int err = -ENOENT;
+	uid_t auid;
+
+	auid = NETLINK_CB(skb).loginuid;
 
 	if (p->index)
-		xp = xfrm_policy_byid(p->dir, p->index, 0);
+		xp = xfrm_policy_byid(p->dir, p->index, 0, auid);
 	else {
 		struct rtattr **rtattrs = (struct rtattr **)xfrma;
 		struct rtattr *rt = rtattrs[XFRMA_SEC_CTX-1];
@@ -1270,7 +1276,7 @@ static int xfrm_add_pol_expire(struct sk
 			if ((err = security_xfrm_policy_alloc(&tmp, uctx)))
 				return err;
 		}
-		xp = xfrm_policy_bysel_ctx(p->dir, &p->sel, tmp.security, 0);
+		xp = xfrm_policy_bysel_ctx(p->dir, &p->sel, tmp.security, 0, auid);
 		security_xfrm_policy_free(&tmp);
 	}
 
@@ -1285,7 +1291,7 @@ static int xfrm_add_pol_expire(struct sk
 	read_unlock(&xp->lock);
 	err = 0;
 	if (up->hard) {
-		xfrm_policy_delete(xp, p->dir);
+		xfrm_policy_delete(xp, p->dir, auid);
 	} else {
 		// reset the timers here?
 		printk("Dont know what to do with soft policy expire\n");
@@ -1318,7 +1324,7 @@ static int xfrm_add_sa_expire(struct sk_
 	km_state_expired(x, ue->hard, current->pid);
 
 	if (ue->hard)
-		__xfrm_state_delete(x);
+		__xfrm_state_delete(x, NETLINK_CB(skb).loginuid);
 out:
 	spin_unlock_bh(&x->lock);
 	xfrm_state_put(x);





More information about the Linux-audit mailing list