auparse delayed event emittance

Steve Grubb sgrubb at redhat.com
Mon Aug 27 13:07:24 UTC 2012


On Saturday, August 18, 2012 10:38:02 AM Giang Nguyen wrote:
> >>     - Do messages from different events ever get intermixed in the
> >> 
> >> output via audispd? And hence I need to cater for multiple simultaneous
> >> events streaming in?
> > 
> > Yes. This is a big problem. About 2 years ago I fixed this in
> > ausearch/report. I started to fix this in libauparse but then I
> > remembered it has this state machine in it to deal with the feed
> > interface. I didn't write that code so it will take some time for me to
> > figure out what it doing before fixing this problem. But basically you
> > need a list of lists where each list is a collection of records that form
> > one event.
> 
> Another, perhaps related, "issue" I have noticed is that libauparse
> (auparse_next_event()), except for some known single-record events,
> relies on a subsequent event coming in to detect that the current
> accumulating event is complete. It compares and sees a different event
> time stamp/serial than the one currently being accumulated. So, if I
> have this sequence:
> 
> event1, record1 (time stamp = X)
> event1, record2
> 
> // 10 seconds elapsed
> 
> event2 (time stamp = Y)
> 
> then libauparse won't call my auparse_callback() to notify me of
> event1 until 10 seconds after event1 happened.
> For my purpose, this delay is not ideal.

auparse should not really be in the business of knowing about time. It doesn't 
know if the higher level program is using SIGALRM or any other timers. So, 
what I would suggest is constructing the event loop something like:

        do {
                fd_set read_mask;
                struct timeval tv;
                int retval;

                /* Re-load configuration */
                if (hup)
                        reload_config();

                do {
                        tv.tv_sec = 4;
                        tv.tv_usec = 0;
                        FD_ZERO(&read_mask);
                        FD_SET(0, &read_mask);
                        retval = select(1, &read_mask, NULL, NULL, &tv);
                } while (retval == -1 && errno == EINTR && !hup && !stop);

                /* Now the event loop */
                 if (!stop && !hup && retval > 0) {
                        if (fgets_unlocked(tmp, MAX_AUDIT_MESSAGE_LENGTH,
                                stdin)) {
                                auparse_feed(au, tmp, strnlen(tmp,
                                                MAX_AUDIT_MESSAGE_LENGTH));
                        }
                } else if (retval == 0)
                        auparse_flush_feed(au);
                if (feof(stdin))
                        break;
        } while (stop == 0);

Which would give you a 4 second delay. If there is not a library function to 
see if something is pending in the feed interface, then perhaps we should make 
one. This way if nothing is in there, the select can go infinite rather than 
busy loop keeping the system from going into a lower power state.

-Steve




More information about the Linux-audit mailing list