Steve,
I have successfully compiled and run following kernels with this patch.
- lspp 55 kernel source with config that comes with it
- lspp 55 kernel source with CONFIG_SELINUX turned off in config
- lspp 55 kernel source with CONFIG_AUDITSYSCALL turned off
(this compilation resulted in my having to add following line to
linux/audit.h so that kernel would compile. Let me know if
that looks ok or not.
+#define audit_log_task_context(b) do { ; } while (0)
If the new line of code I added looks ok, let me know and I will send
patch to netdev and cc you.
When I tested the kernel with CONFIG_AUDITSYSCALL turned off, I
noticed that I did receive the expected messages in the audit.log.
Is that ok? Should I have also turned off CONFIG_AUDIT? Or was I just
ensuring that kernel compiled with CONFIG_AUDITSYSCALL turned off?
Thanks!
Regards,
Joy
----------------------------------------------------------------------------
diff -urpN linux-2.6.18.ppc64.orig/include/linux/audit.h
linux-2.6.18.ppc64.test/include/linux/audit.h
--- linux-2.6.18.ppc64.orig/include/linux/audit.h 2006-11-20 09:52:19.000000000 -0600
+++ linux-2.6.18.ppc64.test/include/linux/audit.h 2006-11-20 18:05:30.000000000 -0600
@@ -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
@@ -376,6 +380,7 @@ extern void auditsc_get_stamp(struct aud
struct timespec *t, unsigned int *serial);
extern int audit_set_loginuid(struct task_struct *task, uid_t loginuid);
extern uid_t audit_get_loginuid(struct audit_context *ctx);
+extern void audit_log_task_context(struct audit_buffer *ab);
extern int __audit_ipc_obj(struct kern_ipc_perm *ipcp);
extern int __audit_ipc_set_perm(unsigned long qbytes, uid_t uid, gid_t gid, mode_t
mode);
extern int audit_bprm(struct linux_binprm *bprm);
@@ -448,6 +453,7 @@ extern int audit_n_rules;
#define audit_inode_update(i) do { ; } while (0)
#define auditsc_get_stamp(c,t,s) do { BUG(); } while (0)
#define audit_get_loginuid(c) ({ -1; })
+#define audit_log_task_context(b) do { ; } while (0)
#define audit_ipc_obj(i) ({ 0; })
#define audit_ipc_set_perm(q,u,g,m) ({ 0; })
#define audit_bprm(p) ({ 0; })
diff -urpN linux-2.6.18.ppc64.orig/include/net/xfrm.h
linux-2.6.18.ppc64.test/include/net/xfrm.h
--- linux-2.6.18.ppc64.orig/include/net/xfrm.h 2006-11-20 09:52:43.000000000 -0600
+++ linux-2.6.18.ppc64.test/include/net/xfrm.h 2006-11-20 11:05:49.000000000 -0600
@@ -371,9 +371,17 @@ struct xfrm_mgr
extern int xfrm_register_km(struct xfrm_mgr *km);
extern int xfrm_unregister_km(struct xfrm_mgr *km);
-
extern struct xfrm_policy *xfrm_policy_list[XFRM_POLICY_MAX*2];
+/* Audit Information */
+struct xfrm_audit
+{
+ uid_t loginuid;
+ u32 secid;
+};
+void xfrm_audit_log(uid_t auid, u32 secid, int type, int result,
+ struct xfrm_policy *xp, struct xfrm_state *x);
+
static inline void xfrm_pol_hold(struct xfrm_policy *policy)
{
if (likely(policy != NULL))
@@ -904,7 +912,7 @@ extern int xfrm_state_update(struct xfrm
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 void xfrm_state_flush(u8 proto, struct xfrm_audit *audit_info);
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);
@@ -952,13 +960,12 @@ int xfrm_policy_insert(int dir, struct x
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);
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(struct xfrm_audit *audit_info);
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.orig/kernel/auditsc.c
linux-2.6.18.ppc64.test/kernel/auditsc.c
--- linux-2.6.18.ppc64.orig/kernel/auditsc.c 2006-11-20 09:51:06.000000000 -0600
+++ linux-2.6.18.ppc64.test/kernel/auditsc.c 2006-11-20 11:02:36.000000000 -0600
@@ -730,7 +730,7 @@ static inline void audit_free_context(st
printk(KERN_ERR "audit: freed %d contexts\n", count);
}
-static void audit_log_task_context(struct audit_buffer *ab)
+void audit_log_task_context(struct audit_buffer *ab)
{
char *ctx = NULL;
ssize_t len = 0;
@@ -759,6 +759,8 @@ error_path:
return;
}
+EXPORT_SYMBOL(audit_log_task_context);
+
static void audit_log_task_info(struct audit_buffer *ab, struct task_struct *tsk)
{
char name[sizeof(tsk->comm)];
@@ -1489,6 +1491,8 @@ 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
* @oflag: open flag
diff -urpN linux-2.6.18.ppc64.orig/net/key/af_key.c
linux-2.6.18.ppc64.test/net/key/af_key.c
--- linux-2.6.18.ppc64.orig/net/key/af_key.c 2006-11-20 09:53:03.000000000 -0600
+++ linux-2.6.18.ppc64.test/net/key/af_key.c 2006-11-20 11:06:15.000000000 -0600
@@ -27,6 +27,7 @@
#include <linux/proc_fs.h>
#include <linux/init.h>
#include <net/xfrm.h>
+#include <linux/audit.h>
#include <net/sock.h>
@@ -1420,6 +1421,9 @@ static int pfkey_add(struct sock *sk, st
else
err = xfrm_state_update(x);
+ xfrm_audit_log(audit_get_loginuid(current->audit_context), 0,
+ AUDIT_MAC_IPSEC_ADDSA, err ? 0 : 1, NULL, x);
+
if (err < 0) {
x->km.state = XFRM_STATE_DEAD;
__xfrm_state_put(x);
@@ -1462,6 +1466,10 @@ static int pfkey_delete(struct sock *sk,
}
err = xfrm_state_delete(x);
+
+ xfrm_audit_log(audit_get_loginuid(current->audit_context), 0,
+ AUDIT_MAC_IPSEC_DELSA, err ? 0 : 1, NULL, x);
+
if (err < 0)
goto out;
@@ -1637,12 +1645,15 @@ static int pfkey_flush(struct sock *sk,
{
unsigned proto;
struct km_event c;
+ struct xfrm_audit audit_info;
proto = pfkey_satype2proto(hdr->sadb_msg_satype);
if (proto == 0)
return -EINVAL;
- xfrm_state_flush(proto);
+ audit_info.loginuid = audit_get_loginuid(current->audit_context);
+ audit_info.secid = 0;
+ xfrm_state_flush(proto, &audit_info);
c.data.proto = proto;
c.seq = hdr->sadb_msg_seq;
c.pid = hdr->sadb_msg_pid;
@@ -2194,6 +2205,8 @@ static int pfkey_spdadd(struct sock *sk,
err = xfrm_policy_insert(pol->sadb_x_policy_dir-1, xp,
hdr->sadb_msg_type != SADB_X_SPDUPDATE);
+ xfrm_audit_log(audit_get_loginuid(current->audit_context), 0,
+ AUDIT_MAC_IPSEC_ADDSPD, err ? 0 : 1, xp, NULL);
if (err)
goto out;
@@ -2270,7 +2283,11 @@ static int pfkey_spddelete(struct sock *
xp = xfrm_policy_bysel_ctx(pol->sadb_x_policy_dir-1, &sel, tmp.security, 1);
security_xfrm_policy_free(&tmp);
- if (xp == NULL)
+
+ xfrm_audit_log(audit_get_loginuid(current->audit_context), 0,
+ AUDIT_MAC_IPSEC_DELSPD, (xp) ? 1 : 0, xp, NULL);
+
+ if (xp == NULL)
return -ENOENT;
err = 0;
@@ -2404,8 +2421,11 @@ static int key_notify_policy_flush(struc
static int pfkey_spdflush(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr,
void **ext_hdrs)
{
struct km_event c;
+ struct xfrm_audit audit_info;
- xfrm_policy_flush();
+ audit_info.loginuid = audit_get_loginuid(current->audit_context);
+ audit_info.secid = 0;
+ xfrm_policy_flush(&audit_info);
c.event = XFRM_MSG_FLUSHPOLICY;
c.pid = hdr->sadb_msg_pid;
c.seq = hdr->sadb_msg_seq;
diff -urpN linux-2.6.18.ppc64.orig/net/xfrm/xfrm_policy.c
linux-2.6.18.ppc64.test/net/xfrm/xfrm_policy.c
--- linux-2.6.18.ppc64.orig/net/xfrm/xfrm_policy.c 2006-11-20 14:03:05.000000000 -0600
+++ linux-2.6.18.ppc64.test/net/xfrm/xfrm_policy.c 2006-11-20 13:49:47.000000000 -0600
@@ -24,6 +24,7 @@
#include <linux/module.h>
#include <net/xfrm.h>
#include <net/ip.h>
+#include <linux/audit.h>
DEFINE_MUTEX(xfrm_cfg_mutex);
EXPORT_SYMBOL(xfrm_cfg_mutex);
@@ -541,7 +542,7 @@ struct xfrm_policy *xfrm_policy_byid(int
}
EXPORT_SYMBOL(xfrm_policy_byid);
-void xfrm_policy_flush(void)
+void xfrm_policy_flush(struct xfrm_audit *audit_info)
{
struct xfrm_policy *xp;
int dir;
@@ -552,6 +553,8 @@ void xfrm_policy_flush(void)
xfrm_policy_list[dir] = xp->next;
write_unlock_bh(&xfrm_policy_lock);
+ xfrm_audit_log(audit_info->loginuid, audit_info->secid,
+ AUDIT_MAC_IPSEC_DELSPD, 1, xp, NULL);
xfrm_policy_kill(xp);
write_lock_bh(&xfrm_policy_lock);
@@ -1367,6 +1370,116 @@ int xfrm_bundle_ok(struct xfrm_policy *p
EXPORT_SYMBOL(xfrm_bundle_ok);
+/* Audit addition and deletion of SAs and ipsec policy */
+
+void xfrm_audit_log(uid_t auid, u32 sid, int type, int result,
+ struct xfrm_policy *xp, struct xfrm_state *x)
+{
+
+ char *secctx;
+ u32 secctx_len;
+ struct xfrm_sec_ctx *sctx = NULL;
+ struct audit_buffer *audit_buf;
+ int family;
+ extern int audit_enabled;
+
+
+ if (audit_enabled == 0)
+ return;
+
+ audit_buf = audit_log_start(current->audit_context, GFP_ATOMIC, type);
+ if (audit_buf == NULL)
+ return;
+
+ switch(type) {
+ case AUDIT_MAC_IPSEC_ADDSA:
+ audit_log_format(audit_buf, "SAD add: auid=%u", auid);
+ break;
+ case AUDIT_MAC_IPSEC_DELSA:
+ audit_log_format(audit_buf, "SAD delete: auid=%u", auid);
+ break;
+ case AUDIT_MAC_IPSEC_ADDSPD:
+ audit_log_format(audit_buf, "SPD add: auid=%u", auid);
+ break;
+ case AUDIT_MAC_IPSEC_DELSPD:
+ audit_log_format(audit_buf, "SPD delete: auid=%u", auid);
+ break;
+ default:
+ return;
+ }
+
+ if (sid != 0 &&
+ security_secid_to_secctx(sid, &secctx, &secctx_len) == 0)
+ audit_log_format(audit_buf, " subj=%s", secctx);
+ else
+ audit_log_task_context(audit_buf);
+
+ if (xp) {
+ family = xp->selector.family;
+ if (xp->security)
+ sctx = xp->security;
+ } else {
+ family = x->props.family;
+ if (x->security)
+ sctx = x->security;
+ }
+
+ if (sctx)
+ audit_log_format(audit_buf,
+ " sec_alg=%u sec_doi=%u sec_obj=%s",
+ sctx->ctx_alg, sctx->ctx_doi, sctx->ctx_str);
+
+ switch(family) {
+ case AF_INET:
+ {
+ struct in_addr saddr, daddr;
+ if (xp) {
+ saddr.s_addr = xp->selector.saddr.a4;
+ daddr.s_addr = xp->selector.daddr.a4;
+ } else {
+ saddr.s_addr = x->props.saddr.a4;
+ daddr.s_addr = x->id.daddr.a4;
+ }
+ audit_log_format(audit_buf,
+ " src=%u.%u.%u.%u dst=%u.%u.%u.%u",
+ NIPQUAD(saddr), NIPQUAD(daddr));
+ }
+ break;
+ case AF_INET6:
+ {
+ struct in6_addr saddr6, daddr6;
+ if (xp) {
+ memcpy(&saddr6, xp->selector.saddr.a6,
+ sizeof(struct in6_addr));
+ memcpy(&daddr6, xp->selector.daddr.a6,
+ sizeof(struct in6_addr));
+ } else {
+ memcpy(&saddr6, x->props.saddr.a6,
+ sizeof(struct in6_addr));
+ memcpy(&daddr6, x->id.daddr.a6,
+ sizeof(struct in6_addr));
+ }
+ audit_log_format(audit_buf,
+ " src=" NIP6_FMT "dst=" NIP6_FMT,
+ NIP6(saddr6), NIP6(daddr6));
+ }
+ break;
+ }
+
+ if (x)
+ audit_log_format(audit_buf, " spi=%lu(0x%lx) protocol=%s",
+ (unsigned long)ntohl(x->id.spi),
+ (unsigned long)ntohl(x->id.spi),
+ x->id.proto == IPPROTO_AH ? "AH" :
+ (x->id.proto == IPPROTO_ESP ?
+ "ESP" : "IPCOMP"));
+
+ audit_log_format(audit_buf, " res=%u", result);
+ audit_log_end(audit_buf);
+}
+
+EXPORT_SYMBOL(xfrm_audit_log);
+
int xfrm_policy_register_afinfo(struct xfrm_policy_afinfo *afinfo)
{
int err = 0;
diff -urpN linux-2.6.18.ppc64.orig/net/xfrm/xfrm_state.c
linux-2.6.18.ppc64.test/net/xfrm/xfrm_state.c
--- linux-2.6.18.ppc64.orig/net/xfrm/xfrm_state.c 2006-11-20 14:03:08.000000000 -0600
+++ linux-2.6.18.ppc64.test/net/xfrm/xfrm_state.c 2006-11-20 13:50:03.000000000 -0600
@@ -19,6 +19,7 @@
#include <linux/ipsec.h>
#include <linux/module.h>
#include <asm/uaccess.h>
+#include <linux/audit.h>
struct sock *xfrm_nl;
EXPORT_SYMBOL(xfrm_nl);
@@ -123,6 +124,7 @@ static void xfrm_timer_handler(unsigned
unsigned long now = (unsigned long)xtime.tv_sec;
long next = LONG_MAX;
int warn = 0;
+ int err = 0;
spin_lock(&x->lock);
if (x->km.state == XFRM_STATE_DEAD)
@@ -180,8 +182,13 @@ expired:
next = 2;
goto resched;
}
- if (!__xfrm_state_delete(x) && x->id.spi)
+
+ err = __xfrm_state_delete(x);
+ if (!err && x->id.spi)
km_state_expired(x, 1, 0);
+
+ xfrm_audit_log(audit_get_loginuid(current->audit_context), 0,
+ AUDIT_MAC_IPSEC_DELSA, err ? 0 : 1, NULL, x);
out:
spin_unlock(&x->lock);
@@ -284,10 +291,11 @@ int xfrm_state_delete(struct xfrm_state
}
EXPORT_SYMBOL(xfrm_state_delete);
-void xfrm_state_flush(u8 proto)
+void xfrm_state_flush(u8 proto, struct xfrm_audit *audit_info)
{
int i;
struct xfrm_state *x;
+ int err = 0;
spin_lock_bh(&xfrm_state_lock);
for (i = 0; i < XFRM_DST_HSIZE; i++) {
@@ -298,7 +306,13 @@ restart:
xfrm_state_hold(x);
spin_unlock_bh(&xfrm_state_lock);
- xfrm_state_delete(x);
+ err = xfrm_state_delete(x);
+
+ xfrm_audit_log(audit_info->loginuid,
+ audit_info->secid,
+ AUDIT_MAC_IPSEC_DELSA,
+ err ? 0 : 1, NULL, x);
+
xfrm_state_put(x);
spin_lock_bh(&xfrm_state_lock);
@@ -1130,6 +1144,7 @@ void xfrm_state_delete_tunnel(struct xfr
if (atomic_read(&t->tunnel_users) == 2)
xfrm_state_delete(t);
+
atomic_dec(&t->tunnel_users);
xfrm_state_put(t);
x->tunnel = NULL;
diff -urpN linux-2.6.18.ppc64.orig/net/xfrm/xfrm_user.c
linux-2.6.18.ppc64.test/net/xfrm/xfrm_user.c
--- linux-2.6.18.ppc64.orig/net/xfrm/xfrm_user.c 2006-11-20 09:53:04.000000000 -0600
+++ linux-2.6.18.ppc64.test/net/xfrm/xfrm_user.c 2006-11-20 11:06:17.000000000 -0600
@@ -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)
{
@@ -400,6 +401,9 @@ static int xfrm_add_sa(struct sk_buff *s
else
err = xfrm_state_update(x);
+ xfrm_audit_log(NETLINK_CB(skb).loginuid, NETLINK_CB(skb).sid,
+ AUDIT_MAC_IPSEC_ADDSA, err ? 0 : 1, NULL, x);
+
if (err < 0) {
x->km.state = XFRM_STATE_DEAD;
__xfrm_state_put(x);
@@ -436,6 +440,10 @@ static int xfrm_del_sa(struct sk_buff *s
}
err = xfrm_state_delete(x);
+
+ xfrm_audit_log(NETLINK_CB(skb).loginuid, NETLINK_CB(skb).sid,
+ AUDIT_MAC_IPSEC_DELSA, err ? 0 : 1, NULL, x);
+
if (err < 0)
goto out;
@@ -860,6 +868,10 @@ static int xfrm_add_policy(struct sk_buf
* a type XFRM_MSG_UPDPOLICY - JHS */
excl = nlh->nlmsg_type == XFRM_MSG_NEWPOLICY;
err = xfrm_policy_insert(p->dir, xp, excl);
+
+ xfrm_audit_log(NETLINK_CB(skb).loginuid, NETLINK_CB(skb).sid,
+ AUDIT_MAC_IPSEC_DELSPD, err ? 0 : 1, xp, NULL);
+
if (err) {
security_xfrm_policy_free(xp);
kfree(xp);
@@ -1055,6 +1067,11 @@ static int xfrm_get_policy(struct sk_buf
xp = xfrm_policy_bysel_ctx(p->dir, &p->sel, tmp.security, delete);
security_xfrm_policy_free(&tmp);
}
+
+ if (delete)
+ xfrm_audit_log(NETLINK_CB(skb).loginuid, NETLINK_CB(skb).sid,
+ AUDIT_MAC_IPSEC_DELSPD, (xp) ? 1 : 0, xp, NULL);
+
if (xp == NULL)
return -ENOENT;
@@ -1089,8 +1106,11 @@ static int xfrm_flush_sa(struct sk_buff
{
struct km_event c;
struct xfrm_usersa_flush *p = NLMSG_DATA(nlh);
+ struct xfrm_audit audit_info;
- xfrm_state_flush(p->proto);
+ audit_info.loginuid = NETLINK_CB(skb).loginuid;
+ audit_info.secid = NETLINK_CB(skb).sid;
+ xfrm_state_flush(p->proto, &audit_info);
c.data.proto = p->proto;
c.event = nlh->nlmsg_type;
c.seq = nlh->nlmsg_seq;
@@ -1235,9 +1255,12 @@ out:
static int xfrm_flush_policy(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma)
{
-struct km_event c;
+ struct km_event c;
+ struct xfrm_audit audit_info;
- xfrm_policy_flush();
+ audit_info.loginuid = NETLINK_CB(skb).loginuid;
+ audit_info.secid = NETLINK_CB(skb).sid;
+ xfrm_policy_flush(&audit_info);
c.event = nlh->nlmsg_type;
c.seq = nlh->nlmsg_seq;
c.pid = nlh->nlmsg_pid;
@@ -1286,6 +1309,8 @@ static int xfrm_add_pol_expire(struct sk
err = 0;
if (up->hard) {
xfrm_policy_delete(xp, p->dir);
+ xfrm_audit_log(NETLINK_CB(skb).loginuid, NETLINK_CB(skb).sid,
+ AUDIT_MAC_IPSEC_DELSPD, 1, xp, NULL);
} else {
// reset the timers here?
printk("Dont know what to do with soft policy expire\n");
@@ -1317,8 +1342,11 @@ static int xfrm_add_sa_expire(struct sk_
goto out;
km_state_expired(x, ue->hard, current->pid);
- if (ue->hard)
+ if (ue->hard) {
+ xfrm_audit_log(NETLINK_CB(skb).loginuid, NETLINK_CB(skb).sid,
+ AUDIT_MAC_IPSEC_DELSA, 1, NULL, x);
__xfrm_state_delete(x);
+ }
out:
spin_unlock_bh(&x->lock);
xfrm_state_put(x);