svn commit: r184856 - in head/sys: bsm security/audit

Christian S.J. Peron csjp at FreeBSD.org
Tue Nov 11 13:57:04 PST 2008


Author: csjp
Date: Tue Nov 11 21:57:03 2008
New Revision: 184856
URL: http://svn.freebsd.org/changeset/base/184856

Log:
  Add support for extended header BSM tokens.  Currently we use the
  regular header tokens.  The extended header tokens contain an IP
  or IPv6 address which makes it possible to identify which host an
  audit record came from when audit records are centralized.
  
  If the host information has not been specified, the system will
  default to the old style headers.  Otherwise, audit records that
  are created as a result of system calls will contain host information.
  
  This implemented has been designed to be consistent with the Solaris
  implementation.  Host information is set/retrieved using the A_GETKAUDIT
  and A_SETKAUDIT auditon(2) commands.  These commands require that a
  pointer to a auditinfo_addr_t object is passed.  Currently only IP and
  IPv6 address families are supported.
  
  The users pace bits associated with this change will follow in an
  openbsm import.
  
  Reviewed by:	rwatson, (sson, wsalamon (older version))
  MFC after:	1 month

Modified:
  head/sys/bsm/audit_internal.h
  head/sys/bsm/audit_record.h
  head/sys/security/audit/audit.c
  head/sys/security/audit/audit.h
  head/sys/security/audit/audit_bsm.c
  head/sys/security/audit/audit_bsm_token.c
  head/sys/security/audit/audit_private.h
  head/sys/security/audit/audit_syscalls.c

Modified: head/sys/bsm/audit_internal.h
==============================================================================
--- head/sys/bsm/audit_internal.h	Tue Nov 11 17:51:38 2008	(r184855)
+++ head/sys/bsm/audit_internal.h	Tue Nov 11 21:57:03 2008	(r184856)
@@ -72,7 +72,9 @@ typedef	struct au_record	au_record_t;
  * token structures may contain pointers of whose contents we do not know the
  * size (e.g text tokens).
  */
+#define	AUDIT_HEADER_EX_SIZE(a)	((a)->ai_termid.at_type+18+sizeof(u_int32_t))
 #define	AUDIT_HEADER_SIZE	18
+#define	MAX_AUDIT_HEADER_SIZE	(5*sizeof(u_int32_t)+18)
 #define	AUDIT_TRAILER_SIZE	7
 
 /*

Modified: head/sys/bsm/audit_record.h
==============================================================================
--- head/sys/bsm/audit_record.h	Tue Nov 11 17:51:38 2008	(r184855)
+++ head/sys/bsm/audit_record.h	Tue Nov 11 21:57:03 2008	(r184856)
@@ -244,10 +244,13 @@ token_t	*au_to_file(char *file, struct t
 
 token_t	*au_to_header32_tm(int rec_size, au_event_t e_type, au_emod_t e_mod,
 	    struct timeval tm);
+token_t	*au_to_header32_ex_tm(int rec_size, au_event_t e_type, au_emod_t e_mod,
+	    struct timeval tm, struct auditinfo_addr *aia);
 token_t	*au_to_header64_tm(int rec_size, au_event_t e_type, au_emod_t e_mod,
 	    struct timeval tm);
 #if !defined(KERNEL) && !defined(_KERNEL)
 token_t	*au_to_header(int rec_size, au_event_t e_type, au_emod_t e_mod);
+token_t	*au_to_header_ex(int rec_size, au_event_t e_type, au_emod_t e_mod);
 token_t	*au_to_header32(int rec_size, au_event_t e_type, au_emod_t e_mod);
 token_t	*au_to_header64(int rec_size, au_event_t e_type, au_emod_t e_mod);
 #endif

Modified: head/sys/security/audit/audit.c
==============================================================================
--- head/sys/security/audit/audit.c	Tue Nov 11 17:51:38 2008	(r184855)
+++ head/sys/security/audit/audit.c	Tue Nov 11 21:57:03 2008	(r184856)
@@ -158,6 +158,45 @@ struct cv		audit_watermark_cv;
 static struct cv	audit_fail_cv;
 
 /*
+ * Kernel audit information.  This will store the current audit address
+ * or host information that the kernel will use when it's generating
+ * audit records.  This data is modified by the A_GET{SET}KAUDIT auditon(2)
+ * command.
+ */
+static struct auditinfo_addr	audit_kinfo;
+static struct rwlock		audit_kinfo_lock;
+
+#define	KINFO_LOCK_INIT()	rw_init(&audit_kinfo_lock, "kernel audit info lock")
+#define	KINFO_RLOCK()		rw_rlock(&audit_kinfo_lock)
+#define	KINFO_WLOCK()		rw_wlock(&audit_kinfo_lock)
+#define	KINFO_RUNLOCK()		rw_runlock(&audit_kinfo_lock)
+#define	KINFO_WUNLOCK()		rw_wunlock(&audit_kinfo_lock)
+
+void
+audit_set_kinfo(struct auditinfo_addr *ak)
+{
+
+	KASSERT(ak->ai_termid.at_type == AU_IPv4 ||
+	    ak->ai_termid.at_type == AU_IPv6,
+	    ("audit_set_kinfo: invalid address type"));
+	KINFO_WLOCK();
+	audit_kinfo = *ak;
+	KINFO_WUNLOCK();
+}
+
+void
+audit_get_kinfo(struct auditinfo_addr *ak)
+{
+
+	KASSERT(audit_kinfo.ai_termid.at_type == AU_IPv4 ||
+	    audit_kinfo.ai_termid.at_type == AU_IPv6,
+	    ("audit_set_kinfo: invalid address type"));
+	KINFO_RLOCK();
+	*ak = audit_kinfo;
+	KINFO_RUNLOCK();
+}
+
+/*
  * Construct an audit record for the passed thread.
  */
 static int
@@ -241,7 +280,11 @@ audit_init(void)
 	audit_qctrl.aq_bufsz = AQ_BUFSZ;
 	audit_qctrl.aq_minfree = AU_FS_MINFREE;
 
+	audit_kinfo.ai_termid.at_type = AU_IPv4;
+	audit_kinfo.ai_termid.at_addr[0] = INADDR_ANY;
+
 	mtx_init(&audit_mtx, "audit_mtx", NULL, MTX_DEF);
+	KINFO_LOCK_INIT();
 	cv_init(&audit_worker_cv, "audit_worker_cv");
 	cv_init(&audit_watermark_cv, "audit_watermark_cv");
 	cv_init(&audit_fail_cv, "audit_fail_cv");

Modified: head/sys/security/audit/audit.h
==============================================================================
--- head/sys/security/audit/audit.h	Tue Nov 11 17:51:38 2008	(r184855)
+++ head/sys/security/audit/audit.h	Tue Nov 11 21:57:03 2008	(r184856)
@@ -180,6 +180,8 @@ void	 audit_cred_proc1(struct ucred *cre
 void	 audit_proc_coredump(struct thread *td, char *path, int errcode);
 void	 audit_thread_alloc(struct thread *td);
 void	 audit_thread_free(struct thread *td);
+void	 audit_set_kinfo(struct auditinfo_addr *);
+void	 audit_get_kinfo(struct auditinfo_addr *);
 
 /*
  * Define a macro to wrap the audit_arg_* calls by checking the global

Modified: head/sys/security/audit/audit_bsm.c
==============================================================================
--- head/sys/security/audit/audit_bsm.c	Tue Nov 11 17:51:38 2008	(r184855)
+++ head/sys/security/audit/audit_bsm.c	Tue Nov 11 21:57:03 2008	(r184856)
@@ -113,13 +113,34 @@ kau_close(struct au_record *rec, struct 
 	size_t tot_rec_size;
 	token_t *cur, *hdr, *trail;
 	struct timeval tm;
-
-	tot_rec_size = rec->len + AUDIT_HEADER_SIZE + AUDIT_TRAILER_SIZE;
+	size_t hdrsize;
+	struct auditinfo_addr ak;
+	struct in6_addr *ap;
+
+	audit_get_kinfo(&ak);
+	hdrsize = 0;
+	switch (ak.ai_termid.at_type) {
+	case AU_IPv4:
+		hdrsize = (ak.ai_termid.at_addr[0] == INADDR_ANY) ?
+		    AUDIT_HEADER_SIZE : AUDIT_HEADER_EX_SIZE(&ak);
+		break;
+	case AU_IPv6:
+		ap = (struct in6_addr *)&ak.ai_termid.at_addr[0];
+		hdrsize = (IN6_IS_ADDR_UNSPECIFIED(ap)) ? AUDIT_HEADER_SIZE :
+		    AUDIT_HEADER_EX_SIZE(&ak);
+		break;
+	default:
+		panic("kau_close: invalid address family");
+	}
+	tot_rec_size = rec->len + hdrsize + AUDIT_TRAILER_SIZE;
 	rec->data = malloc(tot_rec_size, M_AUDITBSM, M_WAITOK | M_ZERO);
 
 	tm.tv_usec = ctime->tv_nsec / 1000;
 	tm.tv_sec = ctime->tv_sec;
-	hdr = au_to_header32_tm(tot_rec_size, event, 0, tm);
+	if (hdrsize != AUDIT_HEADER_SIZE)
+		hdr = au_to_header32_ex_tm(tot_rec_size, event, 0, tm, &ak);
+	else
+		hdr = au_to_header32_tm(tot_rec_size, event, 0, tm);
 	TAILQ_INSERT_HEAD(&rec->token_q, hdr, tokens);
 
 	trail = au_to_trailer(tot_rec_size);

Modified: head/sys/security/audit/audit_bsm_token.c
==============================================================================
--- head/sys/security/audit/audit_bsm_token.c	Tue Nov 11 17:51:38 2008	(r184855)
+++ head/sys/security/audit/audit_bsm_token.c	Tue Nov 11 21:57:03 2008	(r184856)
@@ -1292,6 +1292,51 @@ au_to_exec_env(char **envp)
 /*
  * token ID                1 byte
  * record byte count       4 bytes
+ * version #               1 byte
+ * event type              2 bytes
+ * event modifier          2 bytes
+ * address type/length     4 bytes
+ * machine address         4 bytes/16 bytes (IPv4/IPv6 address)
+ * seconds of time         4 bytes/8 bytes  (32/64-bits)
+ * milliseconds of time    4 bytes/8 bytes  (32/64-bits) 
+ */
+token_t *
+au_to_header32_ex_tm(int rec_size, au_event_t e_type, au_emod_t e_mod,
+    struct timeval tm, struct auditinfo_addr *aia)
+{
+	token_t *t;  
+	u_char *dptr = NULL;
+	u_int32_t timems;
+	struct au_tid_addr *tid;
+
+	tid = &aia->ai_termid;
+	KASSERT(tid->at_type == AU_IPv4 || tid->at_type == AU_IPv6,
+	    ("au_to_header32_ex_tm: invalid address family"));
+
+	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) +
+	    sizeof(u_char) + 2 * sizeof(u_int16_t) + 3 * sizeof(u_int32_t) +
+	    tid->at_type);
+
+	ADD_U_CHAR(dptr, AUT_HEADER32_EX);
+	ADD_U_INT32(dptr, rec_size);
+	ADD_U_CHAR(dptr, AUDIT_HEADER_VERSION_OPENBSM);
+	ADD_U_INT16(dptr, e_type);
+	ADD_U_INT16(dptr, e_mod);
+	ADD_U_INT32(dptr, tid->at_type);
+	if (tid->at_type == AU_IPv6)
+		ADD_MEM(dptr, &tid->at_addr[0], 4 * sizeof(u_int32_t));
+	else
+		ADD_MEM(dptr, &tid->at_addr[0], sizeof(u_int32_t));
+	timems = tm.tv_usec / 1000;
+	/* Add the timestamp */
+	ADD_U_INT32(dptr, tm.tv_sec);
+	ADD_U_INT32(dptr, timems);      /* We need time in ms. */
+	return (t);
+}
+
+/*
+ * token ID                1 byte
+ * record byte count       4 bytes
  * version #               1 byte    [2]
  * event type              2 bytes
  * event modifier          2 bytes

Modified: head/sys/security/audit/audit_private.h
==============================================================================
--- head/sys/security/audit/audit_private.h	Tue Nov 11 17:51:38 2008	(r184855)
+++ head/sys/security/audit/audit_private.h	Tue Nov 11 21:57:03 2008	(r184856)
@@ -132,6 +132,7 @@ union auditon_udata {
 	au_qctrl_t		au_qctrl;
 	au_stat_t		au_stat;
 	au_fstat_t		au_fstat;
+	auditinfo_addr_t	au_kau_info;
 };
 
 struct posix_ipc_perm {

Modified: head/sys/security/audit/audit_syscalls.c
==============================================================================
--- head/sys/security/audit/audit_syscalls.c	Tue Nov 11 17:51:38 2008	(r184855)
+++ head/sys/security/audit/audit_syscalls.c	Tue Nov 11 21:57:03 2008	(r184856)
@@ -395,11 +395,14 @@ auditon(struct thread *td, struct audito
 		break;
 
 	case A_GETKAUDIT:
-		return (ENOSYS);
+		audit_get_kinfo(&udata.au_kau_info);
 		break;
 
 	case A_SETKAUDIT:
-		return (ENOSYS);
+		if (udata.au_kau_info.ai_termid.at_type != AU_IPv4 &&
+		    udata.au_kau_info.ai_termid.at_type != AU_IPv6)
+			return (EINVAL);
+		audit_set_kinfo(&udata.au_kau_info);
 		break;
 
 	case A_SENDTRIGGER:


More information about the svn-src-head mailing list