linux-audit.redhat.com archive mirror
 help / color / mirror / Atom feed
* Patch to auparse to handle out of order messages 1 of 3
@ 2016-01-06 10:29 Burn Alting
  2016-01-06 15:43 ` Steve Grubb
  0 siblings, 1 reply; 2+ messages in thread
From: Burn Alting @ 2016-01-06 10:29 UTC (permalink / raw)
  To: linux-audit@redhat.com

[-- Attachment #1: Type: text/plain, Size: 1004 bytes --]

All,

The TODO for 2.5.1 requested 

	* Fix auparse to handle out of order messages

The problem was that should a stream of raw auditd logs be processed by
auparse(), then if the records that make up a single auditd event were
interleaved with each other, auparse() would 'silently' discard event
data.

Ausearch/Aureport does not have this problem as it handles such
interleaved event records. The approach to solve this problem was to
take the ausearch/aureport's list of list event record code (lol) and
incorporate it into auparse().

The following three patches address this problem.

#1 - convert the existing code to change auparse's auparse_state_t (aka
struct opaque) event_list_t element 'le' to be a pointer, so the 'lol'
code can more seamlessly fit in.

#2 - the 'lol' patch itself. Integrate the ausearch/aureport 'lol' code
into auparse() and adjust auparse() to deal with maintain an incore list
of incomplete events.

#3 - modify the standard auparse() test code.

Regards
Burn Alting 

[-- Attachment #2: audit-2.4.5-1.patch --]
[-- Type: text/x-patch, Size: 14543 bytes --]

diff -urp audit-2.4.5.orig/auparse/auparse.c audit-2.4.5/auparse/auparse.c
--- audit-2.4.5.orig/auparse/auparse.c	2015-12-19 06:20:59.000000000 +1100
+++ audit-2.4.5/auparse/auparse.c	2016-01-03 14:05:15.858351108 +1100
@@ -120,6 +120,13 @@ auparse_state_t *auparse_init(ausource_t
 		return NULL;
 	}
 
+	au->le = NULL;
+	/* Allocate the 'current' event of interest pointer */
+	if ((au->le = (event_list_t *)malloc(sizeof(event_list_t))) == NULL) {
+		free(au);
+		errno = ENOMEM;
+		return NULL;
+	}
 	au->in = NULL;
 	au->source_list = NULL;
 	databuf_init(&au->databuf, 0, 0);
@@ -206,7 +213,7 @@ auparse_state_t *auparse_init(ausource_t
 	au->off = 0;
 	au->cur_buf = NULL;
 	au->line_pushed = 0;
-	aup_list_create(&au->le);
+	aup_list_create(au->le);	/* Initialise the 'current' event pointer */
 	au->parse_state = EVENT_EMPTY;
 	au->expr = NULL;
 	au->find_field = NULL;
@@ -215,6 +222,7 @@ auparse_state_t *auparse_init(ausource_t
 	return au;
 bad_exit:
 	databuf_free(&au->databuf);
+	free(au->le);	/* Free the 'current' event of interest event pointer */
 	free(au);
 	return NULL;
 }
@@ -251,8 +259,8 @@ static void consume_feed(auparse_state_t
 		// to consume any partial data not fully consumed.
 		if (au->parse_state == EVENT_ACCUMULATING) {
 			// Emit the event, set event cursors to initial position
-			aup_list_first(&au->le);
-			aup_list_first_field(&au->le);
+			aup_list_first(au->le);
+			aup_list_first_field(au->le);
 			au->parse_state = EVENT_EMITTED;
 			if (au->callback) {
 				 (*au->callback)(au, AUPARSE_CB_EVENT_READY,
@@ -297,7 +305,9 @@ int auparse_reset(auparse_state_t *au)
 		return -1;
 	}
 
-	aup_list_clear(&au->le);
+	/* Free the 'current' event of interest list and it's content */
+	if (au->le)
+		aup_list_clear(au->le);
 	au->parse_state = EVENT_EMPTY;
 	switch (au->source)
 	{
@@ -547,7 +557,10 @@ void auparse_destroy(auparse_state_t *au
 	au->next_buf = NULL;
         free(au->cur_buf);
 	au->cur_buf = NULL;
-	aup_list_clear(&au->le);
+	/* Reset and clear any data in the 'current' event of interest ptr then free it.  */
+	aup_list_clear(au->le);
+	free(au->le);
+	au->le = NULL;
 	au->parse_state = EVENT_EMPTY;
         free(au->find_field);
 	au->find_field = NULL;
@@ -895,11 +908,11 @@ static int ausearch_reposition_cursors(a
 	switch (au->search_where)
 	{
 		case AUSEARCH_STOP_EVENT:
-			aup_list_first(&au->le);
-			aup_list_first_field(&au->le);
+			aup_list_first(au->le);
+			aup_list_first_field(au->le);
 			break;
 		case AUSEARCH_STOP_RECORD:
-			aup_list_first_field(&au->le);
+			aup_list_first_field(au->le);
 			break;
 		case AUSEARCH_STOP_FIELD:
 			// do nothing - this is the normal stopping point
@@ -917,7 +930,7 @@ static int ausearch_compare(auparse_stat
 {
 	rnode *r;
 
-	r = aup_list_get_cur(&au->le);
+	r = aup_list_get_cur(au->le);
 	if (r)
 		return expr_eval(au, r, au->expr);
 
@@ -962,7 +975,7 @@ int auparse_next_event(auparse_state_t *
 		// If the last call resulted in emitting event data then
 		// clear previous event data in preparation to accumulate
 		// new event data
-		aup_list_clear(&au->le);
+		aup_list_clear(au->le);
 		au->parse_state = EVENT_EMPTY;
 	}
 
@@ -995,17 +1008,17 @@ int auparse_next_event(auparse_state_t *
 				if (debug)
 					printf(
 			"First record in new event, initialize event\n");
-				aup_list_set_event(&au->le, &event);
-				aup_list_append(&au->le, au->cur_buf,
+				aup_list_set_event(au->le, &event);
+				aup_list_append(au->le, au->cur_buf,
 						au->list_idx, au->line_number);
 				au->parse_state = EVENT_ACCUMULATING;
 				au->cur_buf = NULL; 
-			} else if (events_are_equal(&au->le.e, &event)) {
+			} else if (events_are_equal(&au->le->e, &event)) {
 				// Accumulate data into existing event
 				if (debug)
 					printf(
 				    "Accumulate data into existing event\n");
-				aup_list_append(&au->le, au->cur_buf,
+				aup_list_append(au->le, au->cur_buf,
 						au->list_idx, au->line_number);
 				au->parse_state = EVENT_ACCUMULATING;
 				au->cur_buf = NULL; 
@@ -1017,8 +1030,8 @@ int auparse_next_event(auparse_state_t *
 				push_line(au);
 				// Emit the event, set event cursors to 
 				// initial position
-				aup_list_first(&au->le);
-				aup_list_first_field(&au->le);
+				aup_list_first(au->le);
+				aup_list_first_field(au->le);
 				au->parse_state = EVENT_EMITTED;
 				free((char *)event.host);
 				return 1; // data is available
@@ -1027,15 +1040,15 @@ int auparse_next_event(auparse_state_t *
 			// Check to see if the event can be emitted due to EOE
 			// or something we know is a single record event. At
 			// this point, new record should be pointed at 'cur'
-			if ((r = aup_list_get_cur(&au->le)) == NULL)
+			if ((r = aup_list_get_cur(au->le)) == NULL)
 				continue;
 			if (	r->type == AUDIT_EOE ||
 				r->type < AUDIT_FIRST_EVENT ||
 				r->type >= AUDIT_FIRST_ANOM_MSG) {
 				// Emit the event, set event cursors to 
 				// initial position
-				aup_list_first(&au->le);
-				aup_list_first_field(&au->le);
+				aup_list_first(au->le);
+				aup_list_first_field(au->le);
 				au->parse_state = EVENT_EMITTED;
 				return 1; // data is available
 			}
@@ -1048,8 +1061,8 @@ int auparse_next_event(auparse_state_t *
 /* Accessors to event data */
 const au_event_t *auparse_get_timestamp(auparse_state_t *au)
 {
-	if (au && au->le.e.sec != 0)
-		return &au->le.e;
+	if (au && au->le->e.sec != 0)
+		return &au->le->e;
 	else
 		return NULL;
 }
@@ -1058,7 +1071,7 @@ const au_event_t *auparse_get_timestamp(
 time_t auparse_get_time(auparse_state_t *au)
 {
 	if (au)
-		return au->le.e.sec;
+		return au->le->e.sec;
 	else
 		return 0;
 }
@@ -1067,7 +1080,7 @@ time_t auparse_get_time(auparse_state_t
 unsigned int auparse_get_milli(auparse_state_t *au)
 {
 	if (au)
-		return au->le.e.milli;
+		return au->le->e.milli;
 	else
 		return 0;
 }
@@ -1076,7 +1089,7 @@ unsigned int auparse_get_milli(auparse_s
 unsigned long auparse_get_serial(auparse_state_t *au)
 {
 	if (au)
-		return au->le.e.serial;
+		return au->le->e.serial;
 	else
 		return 0;
 }
@@ -1085,8 +1098,8 @@ unsigned long auparse_get_serial(auparse
 // Gets the machine node name
 const char *auparse_get_node(auparse_state_t *au)
 {
-	if (au && au->le.e.host != NULL)
-		return strdup(au->le.e.host);
+	if (au && au->le->e.host != NULL)
+		return strdup(au->le->e.host);
 	else
 		return NULL;
 }
@@ -1130,7 +1143,7 @@ int auparse_timestamp_compare(au_event_t
 
 unsigned int auparse_get_num_records(auparse_state_t *au)
 {
-	return aup_list_get_cnt(&au->le);
+	return aup_list_get_cnt(au->le);
 }
 
 
@@ -1139,13 +1152,13 @@ int auparse_first_record(auparse_state_t
 {
 	int rc;
 
-	if (aup_list_get_cnt(&au->le) == 0) {
+	if (aup_list_get_cnt(au->le) == 0) {
 		rc = auparse_next_event(au);
 		if (rc <= 0)
 			return rc;
 	}
-	aup_list_first(&au->le);
-	aup_list_first_field(&au->le);
+	aup_list_first(au->le);
+	aup_list_first_field(au->le);
 	
 	return 1;
 }
@@ -1153,12 +1166,12 @@ int auparse_first_record(auparse_state_t
 
 int auparse_next_record(auparse_state_t *au)
 {
-	if (aup_list_get_cnt(&au->le) == 0) { 
+	if (aup_list_get_cnt(au->le) == 0) { 
 		int rc = auparse_first_record(au);
 		if (rc <= 0)
 			return rc;
 	}
-	if (aup_list_next(&au->le))
+	if (aup_list_next(au->le))
 		return 1;
 	else
 		return 0;
@@ -1168,10 +1181,10 @@ int auparse_next_record(auparse_state_t
 int auparse_goto_record_num(auparse_state_t *au, unsigned int num)
 {
 	/* Check if a request is out of range */
-	if (num >= aup_list_get_cnt(&au->le))
+	if (num >= aup_list_get_cnt(au->le))
 		return 0;
 
-	if (aup_list_goto_rec(&au->le, num) != NULL)
+	if (aup_list_goto_rec(au->le, num) != NULL)
 		return 1;
 	else
 		return 0;
@@ -1181,7 +1194,7 @@ int auparse_goto_record_num(auparse_stat
 /* Accessors to record data */
 int auparse_get_type(auparse_state_t *au)
 {
-	rnode *r = aup_list_get_cur(&au->le);
+	rnode *r = aup_list_get_cur(au->le);
 	if (r) 
 		return r->type;
 	else
@@ -1191,7 +1204,7 @@ int auparse_get_type(auparse_state_t *au
 
 const char *auparse_get_type_name(auparse_state_t *au)
 {
-	rnode *r = aup_list_get_cur(&au->le);
+	rnode *r = aup_list_get_cur(au->le);
 	if (r)
 		return audit_msg_type_to_name(r->type);
 	else
@@ -1201,7 +1214,7 @@ const char *auparse_get_type_name(aupars
 
 unsigned int auparse_get_line_number(auparse_state_t *au)
 {
-	rnode *r = aup_list_get_cur(&au->le);
+	rnode *r = aup_list_get_cur(au->le);
 	if (r) 
 		return r->line_number;
 	else
@@ -1220,7 +1233,7 @@ const char *auparse_get_filename(auparse
 			return NULL;
 	}
 
-	rnode *r = aup_list_get_cur(&au->le);
+	rnode *r = aup_list_get_cur(au->le);
 	if (r) {
 		if (r->list_idx < 0) return NULL;
 		return au->source_list[r->list_idx];
@@ -1232,13 +1245,13 @@ const char *auparse_get_filename(auparse
 
 int auparse_first_field(auparse_state_t *au)
 {
-	return aup_list_first_field(&au->le);
+	return aup_list_first_field(au->le);
 }
 
 
 int auparse_next_field(auparse_state_t *au)
 {
-	rnode *r = aup_list_get_cur(&au->le);
+	rnode *r = aup_list_get_cur(au->le);
 	if (r) {
 		if (nvlist_next(&r->nv))
 			return 1;
@@ -1251,7 +1264,7 @@ int auparse_next_field(auparse_state_t *
 
 unsigned int auparse_get_num_fields(auparse_state_t *au)
 {
-	rnode *r = aup_list_get_cur(&au->le);
+	rnode *r = aup_list_get_cur(au->le);
 	if (r)
 		return nvlist_get_cnt(&r->nv);
 	else
@@ -1260,7 +1273,7 @@ unsigned int auparse_get_num_fields(aupa
 
 const char *auparse_get_record_text(auparse_state_t *au)
 {
-	rnode *r = aup_list_get_cur(&au->le);
+	rnode *r = aup_list_get_cur(au->le);
 	if (r) 
 		return r->record;
 	else
@@ -1274,12 +1287,12 @@ const char *auparse_find_field(auparse_s
 	free(au->find_field);
 	au->find_field = strdup(name);
 
-	if (au->le.e.sec) {
+	if (au->le->e.sec) {
 		const char *cur_name;
 		rnode *r;
 
 		// look at current record before moving
-		r = aup_list_get_cur(&au->le);
+		r = aup_list_get_cur(au->le);
 		if (r == NULL)
 			return NULL;
 		cur_name = nvlist_get_cur_name(&r->nv);
@@ -1298,10 +1311,10 @@ const char *auparse_find_field_next(aupa
 		errno = EINVAL;
 		return NULL;
 	}
-	if (au->le.e.sec) {
+	if (au->le->e.sec) {
 		int moved = 0;
 
-		rnode *r = aup_list_get_cur(&au->le);
+		rnode *r = aup_list_get_cur(au->le);
 		while (r) {	// For each record in the event...
 			if (!moved) {
 				nvlist_next(&r->nv);
@@ -1309,9 +1322,9 @@ const char *auparse_find_field_next(aupa
 			}
 			if (nvlist_find_name(&r->nv, au->find_field))
 				return nvlist_get_cur_val(&r->nv);
-			r = aup_list_next(&au->le);
+			r = aup_list_next(au->le);
 			if (r)
-				aup_list_first_field(&au->le);
+				aup_list_first_field(au->le);
 		}
 	}
 	return NULL;
@@ -1321,8 +1334,8 @@ const char *auparse_find_field_next(aupa
 /* Accessors to field data */
 const char *auparse_get_field_name(auparse_state_t *au)
 {
-	if (au->le.e.sec) {
-		rnode *r = aup_list_get_cur(&au->le);
+	if (au->le->e.sec) {
+		rnode *r = aup_list_get_cur(au->le);
 		if (r) 
 			return nvlist_get_cur_name(&r->nv);
 	}
@@ -1332,8 +1345,8 @@ const char *auparse_get_field_name(aupar
 
 const char *auparse_get_field_str(auparse_state_t *au)
 {
-	if (au->le.e.sec) {
-		rnode *r = aup_list_get_cur(&au->le);
+	if (au->le->e.sec) {
+		rnode *r = aup_list_get_cur(au->le);
 		if (r) 
 			return nvlist_get_cur_val(&r->nv);
 	}
@@ -1342,8 +1355,8 @@ const char *auparse_get_field_str(aupars
 
 int auparse_get_field_type(auparse_state_t *au)
 {
-        if (au->le.e.sec) {
-                rnode *r = aup_list_get_cur(&au->le);
+        if (au->le->e.sec) {
+                rnode *r = aup_list_get_cur(au->le);
                 if (r)
                         return nvlist_get_cur_type(r);
         }
@@ -1367,8 +1380,8 @@ int auparse_get_field_int(auparse_state_
 
 const char *auparse_interpret_field(auparse_state_t *au)
 {
-        if (au->le.e.sec) {
-                rnode *r = aup_list_get_cur(&au->le);
+        if (au->le->e.sec) {
+                rnode *r = aup_list_get_cur(au->le);
                 if (r)
                         return nvlist_interp_cur_val(r);
         }
diff -urp audit-2.4.5.orig/auparse/expression.c audit-2.4.5/auparse/expression.c
--- audit-2.4.5.orig/auparse/expression.c	2015-12-19 06:20:59.000000000 +1100
+++ audit-2.4.5/auparse/expression.c	2016-01-03 13:46:09.839274892 +1100
@@ -974,13 +974,13 @@ compare_values(auparse_state_t *au, rnod
 	}
 	switch (expr->v.p.field.id) {
 	case EF_TIMESTAMP:
-		if (au->le.e.sec < expr->v.p.value.timestamp.sec)
+		if (au->le->e.sec < expr->v.p.value.timestamp.sec)
 			res = -1;
-		else if (au->le.e.sec > expr->v.p.value.timestamp.sec)
+		else if (au->le->e.sec > expr->v.p.value.timestamp.sec)
 			res = 1;
-		else if (au->le.e.milli < expr->v.p.value.timestamp.milli)
+		else if (au->le->e.milli < expr->v.p.value.timestamp.milli)
 			res = -1;
-		else if (au->le.e.milli > expr->v.p.value.timestamp.milli)
+		else if (au->le->e.milli > expr->v.p.value.timestamp.milli)
 			res = 1;
 		else
 			res = 0;
@@ -996,17 +996,17 @@ compare_values(auparse_state_t *au, rnod
 		break;
 
 	case EF_TIMESTAMP_EX:
-		if (au->le.e.sec < expr->v.p.value.timestamp.sec)
+		if (au->le->e.sec < expr->v.p.value.timestamp.sec)
 			res = -1;
-		else if (au->le.e.sec > expr->v.p.value.timestamp.sec)
+		else if (au->le->e.sec > expr->v.p.value.timestamp.sec)
 			res = 1;
-		else if (au->le.e.milli < expr->v.p.value.timestamp.milli)
+		else if (au->le->e.milli < expr->v.p.value.timestamp.milli)
 			res = -1;
-		else if (au->le.e.milli > expr->v.p.value.timestamp.milli)
+		else if (au->le->e.milli > expr->v.p.value.timestamp.milli)
 			res = 1;
-		else if (au->le.e.serial < expr->v.p.value.timestamp_ex.serial)
+		else if (au->le->e.serial < expr->v.p.value.timestamp_ex.serial)
 			res = -1;
-		else if (au->le.e.serial > expr->v.p.value.timestamp_ex.serial)
+		else if (au->le->e.serial > expr->v.p.value.timestamp_ex.serial)
 			res = 1;
 		else
 			res = 0;
diff -urp audit-2.4.5.orig/auparse/internal.h audit-2.4.5/auparse/internal.h
--- audit-2.4.5.orig/auparse/internal.h	2015-12-19 06:20:59.000000000 +1100
+++ audit-2.4.5/auparse/internal.h	2016-01-03 13:44:33.399504620 +1100
@@ -56,7 +56,7 @@ struct opaque
 	char *cur_buf;			// The current buffer being parsed
 	int line_pushed;		// True if retrieve_next_line() 
 					//	returns same input
-	event_list_t le;		// Linked list of record in same event
+	event_list_t * le;		// Linked list of record in same event
 	struct expr *expr;		// Search expression or NULL
 	char *find_field;		// Used to store field name when
 					//	 searching

[-- Attachment #3: Type: text/plain, Size: 0 bytes --]



^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: Patch to auparse to handle out of order messages 1 of 3
  2016-01-06 10:29 Patch to auparse to handle out of order messages 1 of 3 Burn Alting
@ 2016-01-06 15:43 ` Steve Grubb
  0 siblings, 0 replies; 2+ messages in thread
From: Steve Grubb @ 2016-01-06 15:43 UTC (permalink / raw)
  To: linux-audit, burn

On Wednesday, January 06, 2016 09:29:17 PM Burn Alting wrote:
> The following three patches address this problem.
> 
> #1 - convert the existing code to change auparse's auparse_state_t (aka
> struct opaque) event_list_t element 'le' to be a pointer, so the 'lol'
> code can more seamlessly fit in.

Applied thanks!

-Steve

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2016-01-06 15:43 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-01-06 10:29 Patch to auparse to handle out of order messages 1 of 3 Burn Alting
2016-01-06 15:43 ` Steve Grubb

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).