From mboxrd@z Thu Jan 1 00:00:00 1970 From: Joy Latten Subject: [PATCH 1/1]: ipsec audit Date: Thu, 26 Oct 2006 19:23:18 -0500 Message-ID: <1161908598.17737.280.camel@faith.austin.ibm.com> Mime-Version: 1.0 Content-Type: text/plain Content-Transfer-Encoding: 7bit Return-path: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: linux-audit-bounces@redhat.com Errors-To: linux-audit-bounces@redhat.com To: sgrubb@redhat.com, linux-audit@redhat.com List-Id: linux-audit@redhat.com 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 #include #include +#include #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 #include #include +#include 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 #include #include +#include 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 #include +#include #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 #include #include +#include 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);