* 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).