Re: [PATCH v2] XFRM: assorted IPsec fixups
by Paul Moore
On Tuesday 11 December 2007 12:19:57 pm YOSHIFUJI Hideaki / 吉藤英明 wrote:
> Please do not mangle tabs into spaces.
Yes indeed. Not quite sure what happened there but I just fixed it.
Thanks for pointing that out.
--
paul moore
linux security @ hp
16 years, 10 months
[PATCH] XFRM: assorted IPsec fixups
by Paul Moore
This patch fixes a number of small but potentially troublesome things in the
XFRM/IPsec code:
* Use the 'audit_enabled' variable already in include/linux/audit.h
Removed the need for extern declarations local to each XFRM audit fuction
* Convert 'sid' to 'secid'
The 'sid' name is specific to SELinux, 'secid' is the common naming
convention used by the kernel when refering to tokenized LSM labels
* Convert address display to use standard NIP* macros
Similar to what was recently done with the SPD audit code, this also
includes the removal of some unnecessary memcpy() calls
* Move common code to xfrm_audit_common_stateinfo()
Code consolidation from the "less is more" book on software development
* Convert the SPI in audit records to host byte order
The current SPI values in the audit record are being displayed in
network byte order, probably not what was intended
* Proper spacing around commas in function arguments
Minor style tweak since I was already touching the code
Signed-off-by: Paul Moore <paul.moore(a)hp.com>
---
include/linux/xfrm.h | 2 +
include/net/xfrm.h | 18 ++++++------
net/xfrm/xfrm_policy.c | 15 +++++-----
net/xfrm/xfrm_state.c | 69 +++++++++++++++++++++--------------------------
security/selinux/xfrm.c | 20 +++++++-------
5 files changed, 58 insertions(+), 66 deletions(-)
diff --git a/include/linux/xfrm.h b/include/linux/xfrm.h
index b58adc5..f75a337 100644
--- a/include/linux/xfrm.h
+++ b/include/linux/xfrm.h
@@ -31,7 +31,7 @@ struct xfrm_sec_ctx {
__u8 ctx_doi;
__u8 ctx_alg;
__u16 ctx_len;
- __u32 ctx_sid;
+ __u32 ctx_secid;
char ctx_str[0];
};
diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 58dfa82..c02e230 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -462,7 +462,7 @@ struct xfrm_audit
};
#ifdef CONFIG_AUDITSYSCALL
-static inline struct audit_buffer *xfrm_audit_start(u32 auid, u32 sid)
+static inline struct audit_buffer *xfrm_audit_start(u32 auid, u32 secid)
{
struct audit_buffer *audit_buf = NULL;
char *secctx;
@@ -475,8 +475,8 @@ static inline struct audit_buffer *xfrm_audit_start(u32 auid, u32 sid)
audit_log_format(audit_buf, "auid=%u", auid);
- if (sid != 0 &&
- security_secid_to_secctx(sid, &secctx, &secctx_len) == 0) {
+ if (secid != 0 &&
+ security_secid_to_secctx(secid, &secctx, &secctx_len) == 0) {
audit_log_format(audit_buf, " subj=%s", secctx);
security_release_secctx(secctx, secctx_len);
} else
@@ -485,13 +485,13 @@ static inline struct audit_buffer *xfrm_audit_start(u32 auid, u32 sid)
}
extern void xfrm_audit_policy_add(struct xfrm_policy *xp, int result,
- u32 auid, u32 sid);
+ u32 auid, u32 secid);
extern void xfrm_audit_policy_delete(struct xfrm_policy *xp, int result,
- u32 auid, u32 sid);
+ u32 auid, u32 secid);
extern void xfrm_audit_state_add(struct xfrm_state *x, int result,
- u32 auid, u32 sid);
+ u32 auid, u32 secid);
extern void xfrm_audit_state_delete(struct xfrm_state *x, int result,
- u32 auid, u32 sid);
+ u32 auid, u32 secid);
#else
#define xfrm_audit_policy_add(x, r, a, s) do { ; } while (0)
#define xfrm_audit_policy_delete(x, r, a, s) do { ; } while (0)
@@ -621,13 +621,13 @@ extern int xfrm_selector_match(struct xfrm_selector *sel, struct flowi *fl,
#ifdef CONFIG_SECURITY_NETWORK_XFRM
/* If neither has a context --> match
- * Otherwise, both must have a context and the sids, doi, alg must match
+ * Otherwise, both must have a context and the secids, doi, alg must match
*/
static inline int xfrm_sec_ctx_match(struct xfrm_sec_ctx *s1, struct xfrm_sec_ctx *s2)
{
return ((!s1 && !s2) ||
(s1 && s2 &&
- (s1->ctx_sid == s2->ctx_sid) &&
+ (s1->ctx_secid == s2->ctx_secid) &&
(s1->ctx_doi == s2->ctx_doi) &&
(s1->ctx_alg == s2->ctx_alg)));
}
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index b702bd8..75f25c4 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -23,6 +23,7 @@
#include <linux/netfilter.h>
#include <linux/module.h>
#include <linux/cache.h>
+#include <linux/audit.h>
#include <net/xfrm.h>
#include <net/ip.h>
@@ -2150,15 +2151,14 @@ static inline void xfrm_audit_common_policyinfo(struct xfrm_policy *xp,
}
}
-void
-xfrm_audit_policy_add(struct xfrm_policy *xp, int result, u32 auid, u32 sid)
+void xfrm_audit_policy_add(struct xfrm_policy *xp, int result,
+ u32 auid, u32 secid)
{
struct audit_buffer *audit_buf;
- extern int audit_enabled;
if (audit_enabled == 0)
return;
- audit_buf = xfrm_audit_start(sid, auid);
+ audit_buf = xfrm_audit_start(secid, auid);
if (audit_buf == NULL)
return;
audit_log_format(audit_buf, " op=SPD-add res=%u", result);
@@ -2167,15 +2167,14 @@ xfrm_audit_policy_add(struct xfrm_policy *xp, int result, u32 auid, u32 sid)
}
EXPORT_SYMBOL_GPL(xfrm_audit_policy_add);
-void
-xfrm_audit_policy_delete(struct xfrm_policy *xp, int result, u32 auid, u32 sid)
+void xfrm_audit_policy_delete(struct xfrm_policy *xp, int result,
+ u32 auid, u32 secid)
{
struct audit_buffer *audit_buf;
- extern int audit_enabled;
if (audit_enabled == 0)
return;
- audit_buf = xfrm_audit_start(sid, auid);
+ audit_buf = xfrm_audit_start(secid, auid);
if (audit_buf == NULL)
return;
audit_log_format(audit_buf, " op=SPD-delete res=%u", result);
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index cf43c49..b291a82 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -19,6 +19,7 @@
#include <linux/ipsec.h>
#include <linux/module.h>
#include <linux/cache.h>
+#include <linux/audit.h>
#include <asm/uaccess.h>
#include "xfrm_hash.h"
@@ -1997,67 +1998,59 @@ void __init xfrm_state_init(void)
static inline void xfrm_audit_common_stateinfo(struct xfrm_state *x,
struct audit_buffer *audit_buf)
{
- if (x->security)
- audit_log_format(audit_buf, " sec_alg=%u sec_doi=%u sec_obj=%s",
- x->security->ctx_alg, x->security->ctx_doi,
- x->security->ctx_str);
+ struct xfrm_sec_ctx *ctx = x->security;
+ u32 spi = ntohl(x->id.spi);
- switch(x->props.family) {
- case AF_INET:
- audit_log_format(audit_buf, " src=%u.%u.%u.%u dst=%u.%u.%u.%u",
- NIPQUAD(x->props.saddr.a4),
- NIPQUAD(x->id.daddr.a4));
- break;
- case AF_INET6:
- {
- struct in6_addr saddr6, daddr6;
-
- 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 (ctx)
+ audit_log_format(audit_buf, " sec_alg=%u sec_doi=%u sec_obj=%s",
+ ctx->ctx_alg, ctx->ctx_doi, ctx->ctx_str);
+
+ switch(x->props.family) {
+ case AF_INET:
+ audit_log_format(audit_buf,
+ " src=" NIPQUAD_FMT " dst=" NIPQUAD_FMT,
+ NIPQUAD(x->props.saddr.a4),
+ NIPQUAD(x->id.daddr.a4));
+ break;
+ case AF_INET6:
+ audit_log_format(audit_buf,
+ " src=" NIP6_FMT " dst=" NIP6_FMT,
+ NIP6(*(struct in6_addr *)x->props.saddr.a6),
+ NIP6(*(struct in6_addr *)x->id.daddr.a6));
+ break;
+ }
+
+ audit_log_format(audit_buf, " spi=%u(0x%x)", spi, spi);
}
-void
-xfrm_audit_state_add(struct xfrm_state *x, int result, u32 auid, u32 sid)
+void xfrm_audit_state_add(struct xfrm_state *x, int result,
+ u32 auid, u32 secid)
{
struct audit_buffer *audit_buf;
- extern int audit_enabled;
if (audit_enabled == 0)
return;
- audit_buf = xfrm_audit_start(sid, auid);
+ audit_buf = xfrm_audit_start(secid, auid);
if (audit_buf == NULL)
return;
- audit_log_format(audit_buf, " op=SAD-add res=%u",result);
+ audit_log_format(audit_buf, " op=SAD-add res=%u", result);
xfrm_audit_common_stateinfo(x, audit_buf);
- audit_log_format(audit_buf, " spi=%lu(0x%lx)",
- (unsigned long)x->id.spi, (unsigned long)x->id.spi);
audit_log_end(audit_buf);
}
EXPORT_SYMBOL_GPL(xfrm_audit_state_add);
-void
-xfrm_audit_state_delete(struct xfrm_state *x, int result, u32 auid, u32 sid)
+void xfrm_audit_state_delete(struct xfrm_state *x, int result,
+ u32 auid, u32 secid)
{
struct audit_buffer *audit_buf;
- extern int audit_enabled;
if (audit_enabled == 0)
return;
- audit_buf = xfrm_audit_start(sid, auid);
+ audit_buf = xfrm_audit_start(secid, auid);
if (audit_buf == NULL)
return;
- audit_log_format(audit_buf, " op=SAD-delete res=%u",result);
+ audit_log_format(audit_buf, " op=SAD-delete res=%u", result);
xfrm_audit_common_stateinfo(x, audit_buf);
- audit_log_format(audit_buf, " spi=%lu(0x%lx)",
- (unsigned long)x->id.spi, (unsigned long)x->id.spi);
audit_log_end(audit_buf);
}
EXPORT_SYMBOL_GPL(xfrm_audit_state_delete);
diff --git a/security/selinux/xfrm.c b/security/selinux/xfrm.c
index e076039..c925880 100644
--- a/security/selinux/xfrm.c
+++ b/security/selinux/xfrm.c
@@ -85,7 +85,7 @@ int selinux_xfrm_policy_lookup(struct xfrm_policy *xp, u32 fl_secid, u8 dir)
if (!selinux_authorizable_ctx(ctx))
return -EINVAL;
- sel_sid = ctx->ctx_sid;
+ sel_sid = ctx->ctx_secid;
}
else
/*
@@ -132,7 +132,7 @@ int selinux_xfrm_state_pol_flow_match(struct xfrm_state *x, struct xfrm_policy *
/* Not a SELinux-labeled SA */
return 0;
- state_sid = x->security->ctx_sid;
+ state_sid = x->security->ctx_secid;
if (fl->secid != state_sid)
return 0;
@@ -175,13 +175,13 @@ int selinux_xfrm_decode_session(struct sk_buff *skb, u32 *sid, int ckall)
struct xfrm_sec_ctx *ctx = x->security;
if (!sid_set) {
- *sid = ctx->ctx_sid;
+ *sid = ctx->ctx_secid;
sid_set = 1;
if (!ckall)
break;
}
- else if (*sid != ctx->ctx_sid)
+ else if (*sid != ctx->ctx_secid)
return -EINVAL;
}
}
@@ -232,7 +232,7 @@ static int selinux_xfrm_sec_ctx_alloc(struct xfrm_sec_ctx **ctxp,
ctx->ctx_str[str_len] = 0;
rc = security_context_to_sid(ctx->ctx_str,
str_len,
- &ctx->ctx_sid);
+ &ctx->ctx_secid);
if (rc)
goto out;
@@ -240,7 +240,7 @@ static int selinux_xfrm_sec_ctx_alloc(struct xfrm_sec_ctx **ctxp,
/*
* Does the subject have permission to set security context?
*/
- rc = avc_has_perm(tsec->sid, ctx->ctx_sid,
+ rc = avc_has_perm(tsec->sid, ctx->ctx_secid,
SECCLASS_ASSOCIATION,
ASSOCIATION__SETCONTEXT, NULL);
if (rc)
@@ -264,7 +264,7 @@ not_from_user:
ctx->ctx_doi = XFRM_SC_DOI_LSM;
ctx->ctx_alg = XFRM_SC_ALG_SELINUX;
- ctx->ctx_sid = sid;
+ ctx->ctx_secid = sid;
ctx->ctx_len = str_len;
memcpy(ctx->ctx_str,
ctx_str,
@@ -341,7 +341,7 @@ int selinux_xfrm_policy_delete(struct xfrm_policy *xp)
int rc = 0;
if (ctx)
- rc = avc_has_perm(tsec->sid, ctx->ctx_sid,
+ rc = avc_has_perm(tsec->sid, ctx->ctx_secid,
SECCLASS_ASSOCIATION,
ASSOCIATION__SETCONTEXT, NULL);
@@ -383,7 +383,7 @@ int selinux_xfrm_state_delete(struct xfrm_state *x)
int rc = 0;
if (ctx)
- rc = avc_has_perm(tsec->sid, ctx->ctx_sid,
+ rc = avc_has_perm(tsec->sid, ctx->ctx_secid,
SECCLASS_ASSOCIATION,
ASSOCIATION__SETCONTEXT, NULL);
@@ -412,7 +412,7 @@ int selinux_xfrm_sock_rcv_skb(u32 isec_sid, struct sk_buff *skb,
if (x && selinux_authorizable_xfrm(x)) {
struct xfrm_sec_ctx *ctx = x->security;
- sel_sid = ctx->ctx_sid;
+ sel_sid = ctx->ctx_secid;
break;
}
}
16 years, 10 months
[PATCH] add uid and comm to OBJ_PID records
by Eric Paris
Add uid and comm collection to OBJ_PID records. This information was
ask for by RHEL users who wanted a better idea where signals were ending
up.
Signed-off-by: Eric Paris <eparis(a)redhat.com>
---
#kill a program running as a different user in a different domain
type=OBJ_PID msg=audit(12/10/2007 15:36:54.328:67) : opid=3018 obj=root:system_r:httpd_t:s0-s0:c0.c1023 uid=test comm=loop
type=SYSCALL msg=audit(12/10/2007 15:36:54.328:67) : arch=x86_64 syscall=kill success=yes exit=0 a0=bca a1=f a2=0 a3=0 items=0 ppid=2189 pid=2194 auid=root uid=root gid=root euid=root suid=root fsuid=root egid=root sgid=root fsgid=root tty=pts0 comm=bash exe=/bin/bash subj=root:system_r:unconfined_t:s0-s0:c0.c1023 key=(null)
## custom program which fork() 2 children, puts them in a grp and kills the grp.
type=OBJ_PID msg=audit(12/10/2007 15:29:59.969:38) : opid=2976 obj=root:system_r:unconfined_t:s0-s0:c0.c1023 uid=root comm=tmp
type=OBJ_PID msg=audit(12/10/2007 15:29:59.969:38) : opid=2975 obj=root:system_r:unconfined_t:s0-s0:c0.c1023 uid=root comm=tmp
type=SYSCALL msg=audit(12/10/2007 15:29:59.969:38) : arch=x86_64 syscall=kill success=yes exit=0 a0=fffff461 a1=9 a2=0 a3=0 items=0 ppid=2194 pid=2974 auid=root uid=root gid=root euid=root suid=root fsuid=root egid=root sgid=root fsgid=root tty=pts0 comm=tmp exe=/tmp/tmp subj=root:system_r:unconfined_t:s0-s0:c0.c1023 key=(null)
kernel/auditsc.c | 21 ++++++++++++++++++---
1 files changed, 18 insertions(+), 3 deletions(-)
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index bce9ecd..dcedbb0 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -176,7 +176,9 @@ struct audit_aux_data_fd_pair {
struct audit_aux_data_pids {
struct audit_aux_data d;
pid_t target_pid[AUDIT_AUX_PIDS];
+ pid_t target_uid[AUDIT_AUX_PIDS];
u32 target_sid[AUDIT_AUX_PIDS];
+ char target_comm[AUDIT_AUX_PIDS][TASK_COMM_LEN];
int pid_count;
};
@@ -215,7 +217,9 @@ struct audit_context {
int arch;
pid_t target_pid;
+ pid_t target_uid;
u32 target_sid;
+ char target_comm[TASK_COMM_LEN];
struct audit_tree_refs *trees, *first_trees;
int tree_count;
@@ -922,7 +926,7 @@ static void audit_log_task_info(struct audit_buffer *ab, struct task_struct *tsk
}
static int audit_log_pid_context(struct audit_context *context, pid_t pid,
- u32 sid)
+ u32 sid, pid_t uid, char *comm)
{
struct audit_buffer *ab;
char *s = NULL;
@@ -938,6 +942,8 @@ static int audit_log_pid_context(struct audit_context *context, pid_t pid,
rc = 1;
} else
audit_log_format(ab, "opid=%d obj=%s", pid, s);
+ audit_log_format(ab, " uid=%d comm=", uid);
+ audit_log_untrustedstring(ab, comm);
audit_log_end(ab);
kfree(s);
@@ -1168,13 +1174,16 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts
for (i = 0; i < axs->pid_count; i++)
if (audit_log_pid_context(context, axs->target_pid[i],
- axs->target_sid[i]))
+ axs->target_sid[i],
+ axs->target_uid[i],
+ axs->target_comm[i]))
call_panic = 1;
}
if (context->target_pid &&
audit_log_pid_context(context, context->target_pid,
- context->target_sid))
+ context->target_sid, context->target_uid,
+ context->target_comm))
call_panic = 1;
if (context->pwd && context->pwdmnt) {
@@ -2194,6 +2203,8 @@ void __audit_ptrace(struct task_struct *t)
context->target_pid = t->pid;
selinux_get_task_sid(t, &context->target_sid);
+ memcpy(context->target_comm, t->comm, TASK_COMM_LEN);
+ context->target_uid = t->uid;
}
/**
@@ -2231,6 +2242,8 @@ int __audit_signal_info(int sig, struct task_struct *t)
if (!ctx->target_pid) {
ctx->target_pid = t->tgid;
selinux_get_task_sid(t, &ctx->target_sid);
+ memcpy(ctx->target_comm, t->comm, TASK_COMM_LEN);
+ ctx->target_uid = t->uid;
return 0;
}
@@ -2248,6 +2261,8 @@ int __audit_signal_info(int sig, struct task_struct *t)
axp->target_pid[axp->pid_count] = t->tgid;
selinux_get_task_sid(t, &axp->target_sid[axp->pid_count]);
+ memcpy(axp->target_comm[axp->pid_count], t->comm, TASK_COMM_LEN);
+ axp->target_uid[axp->pid_count] = t->uid;
axp->pid_count++;
return 0;
16 years, 10 months
processing audit data
by Thorsten Scherf
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
HI folks,
wo we have any plans to ship auditd with some kind of data processing
tool in the future? maybe as audispd plugin? just having a single log
file with a bunch of data isn't really helpful, although we have tools
like ausearch or aureport. customers often ask for something more
visually. :)
Thanks,
Thorsten
- --
Life is complicated, sendmail.cf reflects this!
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.7 (GNU/Linux)
Comment: Using GnuPG with Fedora - http://enigmail.mozdev.org
iD8DBQFHXBq0wfkoLTuSgLsRAtUFAJsFg1Sga8AYFmqEOy70CcCcp5kknACglTY3
mIgugCnhnnrYWzR+0fFyW9g=
=rFNq
-----END PGP SIGNATURE-----
16 years, 11 months
[PATCH] XFRM: RFC4303 compliant auditing
by Paul Moore
NOTE: This really is an RFC patch, it compiles and boots but that is pretty
much all I can promise at this point. I'm posting this patch to gather
feedback from the audit crowd about the continued overloading of
the AUDIT_MAC_IPSEC_EVENT message type - continue to use it or create
a new audit message type? Of course any other comments people may have
are always welcome.
This patch adds a number of new IPsec audit events to meet the auditing
requirements of RFC4303. This includes audit hooks for the following events:
* Could not find a valid SA [sections 2.1, 3.4.2]
. xfrm_audit_state_notfound()
. xfrm_audit_state_notfound_simple()
* Sequence number overflow [section 3.3.3]
. xfrm_audit_state_replay_overflow()
* Replayed packet [section 3.4.3]
. xfrm_audit_state_replay()
* Integrity check failure [sections 3.4.4.1, 3.4.4.2]
. xfrm_audit_state_icvfail()
While RFC4304 deals only with ESP most of the changes in this patch apply to
IPsec in general, i.e. both AH and ESP. The one case, integrity check
failure, where ESP specific code had to be modified the same was done to the
AH code for the sake of consistency.
---
include/net/xfrm.h | 14 ++++
net/ipv4/ah4.c | 1
net/ipv4/esp4.c | 1
net/ipv4/xfrm4_input.c | 6 +-
net/ipv6/ah6.c | 1
net/ipv6/esp6.c | 1
net/ipv6/xfrm6_input.c | 10 ++-
net/xfrm/xfrm_output.c | 2 +
net/xfrm/xfrm_state.c | 155 ++++++++++++++++++++++++++++++++++++++++++++++--
9 files changed, 177 insertions(+), 14 deletions(-)
diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index c02e230..85ce8c1 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -492,11 +492,22 @@ extern void xfrm_audit_state_add(struct xfrm_state *x, int result,
u32 auid, u32 secid);
extern void xfrm_audit_state_delete(struct xfrm_state *x, int result,
u32 auid, u32 secid);
+extern void xfrm_audit_state_replay_overflow(struct xfrm_state *x,
+ struct sk_buff *skb);
+extern void xfrm_audit_state_notfound_simple(struct sk_buff *skb, u16 family);
+extern void xfrm_audit_state_notfound(struct sk_buff *skb, u16 family,
+ __be32 net_spi, __be32 net_seq);
+extern void xfrm_audit_state_icvfail(struct xfrm_state *x,
+ struct sk_buff *skb, u8 proto);
#else
#define xfrm_audit_policy_add(x, r, a, s) do { ; } while (0)
#define xfrm_audit_policy_delete(x, r, a, s) do { ; } while (0)
#define xfrm_audit_state_add(x, r, a, s) do { ; } while (0)
#define xfrm_audit_state_delete(x, r, a, s) do { ; } while (0)
+#define xfrm_audit_state_replay_overflow(x, s) do { ; } while (0)
+#define xfrm_audit_state_notfound_simple(s, f) do { ; } while (0)
+#define xfrm_audit_state_notfound(s, f, sp, sq) do { ; } while (0)
+#define xfrm_audit_state_icvfail(x, s, p) do { ; } while (0)
#endif /* CONFIG_AUDITSYSCALL */
static inline void xfrm_pol_hold(struct xfrm_policy *policy)
@@ -1045,7 +1056,8 @@ extern int xfrm_state_delete(struct xfrm_state *x);
extern int xfrm_state_flush(u8 proto, struct xfrm_audit *audit_info);
extern void xfrm_sad_getinfo(struct xfrmk_sadinfo *si);
extern void xfrm_spd_getinfo(struct xfrmk_spdinfo *si);
-extern int xfrm_replay_check(struct xfrm_state *x, __be32 seq);
+extern int xfrm_replay_check(struct xfrm_state *x,
+ struct sk_buff *skb, __be32 seq);
extern void xfrm_replay_advance(struct xfrm_state *x, __be32 seq);
extern void xfrm_replay_notify(struct xfrm_state *x, int event);
extern int xfrm_state_mtu(struct xfrm_state *x, int mtu);
diff --git a/net/ipv4/ah4.c b/net/ipv4/ah4.c
index 5fc346d..8eb19c9 100644
--- a/net/ipv4/ah4.c
+++ b/net/ipv4/ah4.c
@@ -180,6 +180,7 @@ static int ah_input(struct xfrm_state *x, struct sk_buff *skb)
err = -EINVAL;
if (memcmp(ahp->work_icv, auth_data, ahp->icv_trunc_len)) {
x->stats.integrity_failed++;
+ xfrm_audit_state_icvfail(x, skb, IPPROTO_AH);
goto out;
}
}
diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c
index c31bccb..00ec285 100644
--- a/net/ipv4/esp4.c
+++ b/net/ipv4/esp4.c
@@ -183,6 +183,7 @@ static int esp_input(struct xfrm_state *x, struct sk_buff *skb)
if (unlikely(memcmp(esp->auth.work_icv, sum, alen))) {
x->stats.integrity_failed++;
+ xfrm_audit_state_icvfail(x, skb, IPPROTO_ESP);
goto out;
}
}
diff --git a/net/ipv4/xfrm4_input.c b/net/ipv4/xfrm4_input.c
index 5e95c8a..6d7be5e 100644
--- a/net/ipv4/xfrm4_input.c
+++ b/net/ipv4/xfrm4_input.c
@@ -56,8 +56,10 @@ int xfrm4_rcv_encap(struct sk_buff *skb, int nexthdr, __be32 spi,
x = xfrm_state_lookup((xfrm_address_t *)&iph->daddr, spi,
nexthdr, AF_INET);
- if (x == NULL)
+ if (x == NULL) {
+ xfrm_audit_state_notfound(skb, AF_INET, spi, seq);
goto drop;
+ }
spin_lock(&x->lock);
if (unlikely(x->km.state != XFRM_STATE_VALID))
@@ -66,7 +68,7 @@ int xfrm4_rcv_encap(struct sk_buff *skb, int nexthdr, __be32 spi,
if ((x->encap ? x->encap->encap_type : 0) != encap_type)
goto drop_unlock;
- if (x->props.replay_window && xfrm_replay_check(x, seq))
+ if (x->props.replay_window && xfrm_replay_check(x, skb, seq))
goto drop_unlock;
if (xfrm_state_check_expire(x))
diff --git a/net/ipv6/ah6.c b/net/ipv6/ah6.c
index 4eaf550..b7d2e19 100644
--- a/net/ipv6/ah6.c
+++ b/net/ipv6/ah6.c
@@ -383,6 +383,7 @@ static int ah6_input(struct xfrm_state *x, struct sk_buff *skb)
if (memcmp(ahp->work_icv, auth_data, ahp->icv_trunc_len)) {
LIMIT_NETDEBUG(KERN_WARNING "ipsec ah authentication error\n");
x->stats.integrity_failed++;
+ xfrm_audit_state_icvfail(x, skb, IPPROTO_AH);
goto free_out;
}
}
diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c
index 7db66f1..d56db2b 100644
--- a/net/ipv6/esp6.c
+++ b/net/ipv6/esp6.c
@@ -178,6 +178,7 @@ static int esp6_input(struct xfrm_state *x, struct sk_buff *skb)
if (unlikely(memcmp(esp->auth.work_icv, sum, alen))) {
x->stats.integrity_failed++;
+ xfrm_audit_state_icvfail(x, skb, IPPROTO_ESP);
ret = -EINVAL;
goto out;
}
diff --git a/net/ipv6/xfrm6_input.c b/net/ipv6/xfrm6_input.c
index 5157837..28c1e1b 100644
--- a/net/ipv6/xfrm6_input.c
+++ b/net/ipv6/xfrm6_input.c
@@ -40,13 +40,15 @@ int xfrm6_rcv_spi(struct sk_buff *skb, int nexthdr, __be32 spi)
x = xfrm_state_lookup((xfrm_address_t *)&iph->daddr, spi,
nexthdr, AF_INET6);
- if (x == NULL)
+ if (x == NULL) {
+ xfrm_audit_state_notfound(skb, AF_INET6, spi, seq);
goto drop;
+ }
spin_lock(&x->lock);
if (unlikely(x->km.state != XFRM_STATE_VALID))
goto drop_unlock;
- if (x->props.replay_window && xfrm_replay_check(x, seq))
+ if (x->props.replay_window && xfrm_replay_check(x, skb, seq))
goto drop_unlock;
if (xfrm_state_check_expire(x))
@@ -217,8 +219,10 @@ int xfrm6_input_addr(struct sk_buff *skb, xfrm_address_t *daddr,
break;
}
- if (!xfrm_vec_one)
+ if (!xfrm_vec_one) {
+ xfrm_audit_state_notfound_simple(skb, AF_INET6);
goto drop;
+ }
/* Allocate new secpath or COW existing one. */
if (!skb->sp || atomic_read(&skb->sp->refcnt) != 1) {
diff --git a/net/xfrm/xfrm_output.c b/net/xfrm/xfrm_output.c
index f4bfd6c..14ce897 100644
--- a/net/xfrm/xfrm_output.c
+++ b/net/xfrm/xfrm_output.c
@@ -59,6 +59,8 @@ int xfrm_output(struct sk_buff *skb)
if (x->type->flags & XFRM_TYPE_REPLAY_PROT) {
XFRM_SKB_CB(skb)->seq = ++x->replay.oseq;
+ if (unlikely(x->replay.oseq == 0))
+ xfrm_audit_state_replay_overflow(x, skb);
if (xfrm_aevent_is_on())
xfrm_replay_notify(x, XFRM_REPLAY_UPDATE);
}
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index b291a82..cfef149 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -61,6 +61,13 @@ static unsigned int xfrm_state_genid;
static struct xfrm_state_afinfo *xfrm_state_get_afinfo(unsigned int family);
static void xfrm_state_put_afinfo(struct xfrm_state_afinfo *afinfo);
+#ifdef CONFIG_AUDITSYSCALL
+static void xfrm_audit_state_replay(struct xfrm_state *x,
+ struct sk_buff *skb, __be32 net_seq);
+#else
+#define xfrm_audit_state_replay(x, s, sq) do { ; } while (0)
+#endif /* CONFIG_AUDITSYSCALL */
+
static inline unsigned int xfrm_dst_hash(xfrm_address_t *daddr,
xfrm_address_t *saddr,
u32 reqid,
@@ -1610,13 +1617,14 @@ static void xfrm_replay_timer_handler(unsigned long data)
spin_unlock(&x->lock);
}
-int xfrm_replay_check(struct xfrm_state *x, __be32 net_seq)
+int xfrm_replay_check(struct xfrm_state *x,
+ struct sk_buff *skb, __be32 net_seq)
{
u32 diff;
u32 seq = ntohl(net_seq);
if (unlikely(seq == 0))
- return -EINVAL;
+ goto err;
if (likely(seq > x->replay.seq))
return 0;
@@ -1625,14 +1633,18 @@ int xfrm_replay_check(struct xfrm_state *x, __be32 net_seq)
if (diff >= min_t(unsigned int, x->props.replay_window,
sizeof(x->replay.bitmap) * 8)) {
x->stats.replay_window++;
- return -EINVAL;
+ goto err;
}
if (x->replay.bitmap & (1U << diff)) {
x->stats.replay++;
- return -EINVAL;
+ goto err;
}
return 0;
+
+err:
+ xfrm_audit_state_replay(x, skb, net_seq);
+ return -EINVAL;
}
EXPORT_SYMBOL(xfrm_replay_check);
@@ -1995,8 +2007,8 @@ void __init xfrm_state_init(void)
}
#ifdef CONFIG_AUDITSYSCALL
-static inline void xfrm_audit_common_stateinfo(struct xfrm_state *x,
- struct audit_buffer *audit_buf)
+static inline void xfrm_audit_helper_sainfo(struct xfrm_state *x,
+ struct audit_buffer *audit_buf)
{
struct xfrm_sec_ctx *ctx = x->security;
u32 spi = ntohl(x->id.spi);
@@ -2023,6 +2035,34 @@ static inline void xfrm_audit_common_stateinfo(struct xfrm_state *x,
audit_log_format(audit_buf, " spi=%u(0x%x)", spi, spi);
}
+static inline void xfrm_audit_helper_pktinfo(struct sk_buff *skb, u16 family,
+ struct audit_buffer *audit_buf)
+{
+ struct iphdr *iph4;
+ struct ipv6hdr *iph6;
+
+ switch (family) {
+ case AF_INET:
+ iph4 = ip_hdr(skb);
+ audit_log_format(audit_buf,
+ " src=" NIPQUAD_FMT " dst=" NIPQUAD_FMT,
+ NIPQUAD(iph4->saddr),
+ NIPQUAD(iph4->daddr));
+ break;
+ case AF_INET6:
+ iph6 = ipv6_hdr(skb);
+ audit_log_format(audit_buf,
+ " src=" NIP6_FMT " dst=" NIP6_FMT
+ " flowlbl=0x%x%x%x",
+ NIP6(iph6->saddr),
+ NIP6(iph6->daddr),
+ iph6->flow_lbl[0] & 0x0f,
+ iph6->flow_lbl[1],
+ iph6->flow_lbl[2]);
+ break;
+ }
+}
+
void xfrm_audit_state_add(struct xfrm_state *x, int result,
u32 auid, u32 secid)
{
@@ -2034,7 +2074,7 @@ void xfrm_audit_state_add(struct xfrm_state *x, int result,
if (audit_buf == NULL)
return;
audit_log_format(audit_buf, " op=SAD-add res=%u", result);
- xfrm_audit_common_stateinfo(x, audit_buf);
+ xfrm_audit_helper_sainfo(x, audit_buf);
audit_log_end(audit_buf);
}
EXPORT_SYMBOL_GPL(xfrm_audit_state_add);
@@ -2050,8 +2090,107 @@ void xfrm_audit_state_delete(struct xfrm_state *x, int result,
if (audit_buf == NULL)
return;
audit_log_format(audit_buf, " op=SAD-delete res=%u", result);
- xfrm_audit_common_stateinfo(x, audit_buf);
+ xfrm_audit_helper_sainfo(x, audit_buf);
audit_log_end(audit_buf);
}
EXPORT_SYMBOL_GPL(xfrm_audit_state_delete);
+
+void xfrm_audit_state_replay_overflow(struct xfrm_state *x,
+ struct sk_buff *skb)
+{
+ struct audit_buffer *audit_buf;
+ u32 spi = ntohl(x->id.spi);
+
+ if (audit_enabled == 0)
+ return;
+ audit_buf = audit_log_start(current->audit_context, GFP_ATOMIC,
+ AUDIT_MAC_IPSEC_EVENT);
+ if (audit_buf == NULL)
+ return;
+ audit_log_format(audit_buf, " op=SA-replay-overflow");
+ xfrm_audit_helper_pktinfo(skb, x->props.family, audit_buf);
+ /* don't record the sequence number because it's inherent in this kind
+ * of audit message */
+ audit_log_format(audit_buf, " spi=%u(0x%x)", spi, spi);
+ audit_log_end(audit_buf);
+}
+EXPORT_SYMBOL_GPL(xfrm_audit_state_replay_overflow);
+
+static void xfrm_audit_state_replay(struct xfrm_state *x,
+ struct sk_buff *skb, __be32 net_seq)
+{
+ struct audit_buffer *audit_buf;
+ u32 spi = ntohl(x->id.spi);
+
+ if (audit_enabled == 0)
+ return;
+ audit_buf = audit_log_start(current->audit_context, GFP_ATOMIC,
+ AUDIT_MAC_IPSEC_EVENT);
+ if (audit_buf == NULL)
+ return;
+ audit_log_format(audit_buf, " op=SA-replayed-pkt");
+ xfrm_audit_helper_pktinfo(skb, x->props.family, audit_buf);
+ audit_log_format(audit_buf, " spi=%u(0x%x) seqno=%u",
+ spi, spi, ntohl(net_seq));
+ audit_log_end(audit_buf);
+}
+
+void xfrm_audit_state_notfound_simple(struct sk_buff *skb, u16 family)
+{
+ struct audit_buffer *audit_buf;
+
+ if (audit_enabled == 0)
+ return;
+ audit_buf = audit_log_start(current->audit_context, GFP_ATOMIC,
+ AUDIT_MAC_IPSEC_EVENT);
+ if (audit_buf == NULL)
+ return;
+ audit_log_format(audit_buf, " op=SA-notfound");
+ xfrm_audit_helper_pktinfo(skb, family, audit_buf);
+ audit_log_end(audit_buf);
+}
+EXPORT_SYMBOL_GPL(xfrm_audit_state_notfound_simple);
+
+void xfrm_audit_state_notfound(struct sk_buff *skb, u16 family,
+ __be32 net_spi, __be32 net_seq)
+{
+ struct audit_buffer *audit_buf;
+ u32 spi = ntohl(net_spi);
+
+ if (audit_enabled == 0)
+ return;
+ audit_buf = audit_log_start(current->audit_context, GFP_ATOMIC,
+ AUDIT_MAC_IPSEC_EVENT);
+ if (audit_buf == NULL)
+ return;
+ audit_log_format(audit_buf, " op=SA-notfound");
+ xfrm_audit_helper_pktinfo(skb, family, audit_buf);
+ audit_log_format(audit_buf, " spi=%u(0x%x) seqno=%u",
+ spi, spi, ntohl(net_seq));
+ audit_log_end(audit_buf);
+}
+EXPORT_SYMBOL_GPL(xfrm_audit_state_notfound);
+
+void xfrm_audit_state_icvfail(struct xfrm_state *x,
+ struct sk_buff *skb, u8 proto)
+{
+ struct audit_buffer *audit_buf;
+ __be32 net_spi;
+ __be32 net_seq;
+ u32 spi;
+
+ audit_buf = audit_log_start(current->audit_context, GFP_ATOMIC,
+ AUDIT_MAC_IPSEC_EVENT);
+ if (audit_buf == NULL)
+ return;
+ audit_log_format(audit_buf, " op=SA-icv-failure");
+ xfrm_audit_helper_pktinfo(skb, x->props.family, audit_buf);
+ if (xfrm_parse_spi(skb, proto, &net_spi, &net_seq) == 0) {
+ spi = ntohl(net_spi);
+ audit_log_format(audit_buf, " spi=%u(0x%x) seqno=%u",
+ spi, spi, ntohl(net_seq));
+ }
+ audit_log_end(audit_buf);
+}
+EXPORT_SYMBOL_GPL(xfrm_audit_state_icvfail);
#endif /* CONFIG_AUDITSYSCALL */
16 years, 11 months
Excluding certain audit message types?
by Paul Moore
Hello friendly audit people,
I have a pretty simple question which I hope has a pretty simple answer. Is
it possible to exclude a specific audit message type from the audit log? The
auditctl man page looks like it might be possible using the syntax below but
I'm not sure ...
# auditctl -a exclude,always -F msgtype=1415
--
paul moore
linux security @ hp
16 years, 11 months
auid unset
by Kirkwood, David A.
Hi,
I need some help with configuration. First, I do not remember how to
tell the version of the auditd I am running. I tried to get it by
pulling strings with no success. The larger problem is I am configuring
a RHEL4U5 system. I have a RHEL4U4 system that runs correctly and
supplies the AUID when specified with aureport. The RHEL4U5 system has
this parameter as "unset" rather than the AUID or uid or anything else
to identify who was attempting to run failed commands.
If someone can help me with what needs to be set, I would appreciate it.
I compared all of the obvious files, such as all pam files, the
audit.rules, auditd.conf and syslog.conf and they all seem to be the
same.
Both systems run Linux 2.6.9-42.ELsmp.
Thanks in advance.
David A. Kirkwood
16 years, 11 months
FW: auid unset
by Kirkwood, David A.
Additionally, this appears to only happen when using the command
aureport -I -w --failed
The other au<search|report> commands I use seem to work correctly.
David A. Kirkwood
>Hi,
>I need some help with configuration. First, I do not remember how to
>tell the version of the auditd I am running. I tried to get it by
>pulling strings with no success. The larger problem is I am configuring
>a RHEL4U5 system. I have a RHEL4U4 system that runs correctly and
>supplies the AUID when specified with aureport. The RHEL4U5 system has
>this parameter as "unset" rather than the AUID or uid or anything else
>to identify who was attempting to run failed commands.
>If someone can help me with what needs to be set, I would appreciate
it.
>I compared all of the obvious files, such as all pam files, the
>audit.rules, auditd.conf and syslog.conf and they all seem to be the
>same.
>Both systems run Linux 2.6.9-42.ELsmp.
>Thanks in advance.
>David A. Kirkwood
--
Linux-audit mailing list
Linux-audit(a)redhat.com
https://www.redhat.com/mailman/listinfo/linux-audit
16 years, 11 months
RFC4303 (IPsec/ESP) auditing requirements
by Paul Moore
Hello all,
I'm looking at RFC4303 at some of the auditing requirements and one of the
gaps between what the specification requires and what we currently provide
involves the SA's sequence number and the IPv6 flow ID. According the list
of existing audit fields[1] there doesn't appear to any fields which are a
good match. With that in mind I'd like to propose two new fields:
* seqno - sequence number
* flowid - flow id
Any comments, objections, suggestions?
[1] http://people.redhat.com/sgrubb/audit/audit-parse.txt
--
paul moore
linux security @ hp
16 years, 11 months
auid uset
by Kirkwood, David A.
Hi,
I need some help with configuration. First, I do not remember how to
tell the version of the auditd I am running. I tried to get it
By pulling strings with no success. The larger problem is I am
configuring a RHEL4U5 system. I have a RHEL4U4 system that runs
Correctly and supplies the AUID when specified with aureport. The
RHEL4U5 system has this parameter as "unset" rather than the
AUID or uid or anything else to identify who was attempting to run
failed commands.
If someone can help me with what needs to be set, I would appreciate it.
I compared all of the obvious files, such as all pam files,
the audit.rules, auditd.conf and syslog.conf and they all seem to be the
same.
Thanks in advance..
David A. Kirkwood
16 years, 11 months