Convert the contid list from a list of strings to a list of contids for faster and more efficient processing. Signed-off-by: Richard Guy Briggs <rgb@xxxxxxxxxx> --- src/Makefile.am | 6 +- src/ausearch-contid.c | 171 +++++++++++++++++++++++++++++++++++++++++++++++++ src/ausearch-contid.h | 61 ++++++++++++++++++ src/ausearch-llist.c | 2 +- src/ausearch-llist.h | 3 +- src/ausearch-match.c | 36 +++++------ src/ausearch-options.c | 26 ++++---- src/ausearch-options.h | 3 +- src/ausearch-parse.c | 127 +++++++++++++----------------------- 9 files changed, 313 insertions(+), 122 deletions(-) create mode 100644 src/ausearch-contid.c create mode 100644 src/ausearch-contid.h diff --git a/src/Makefile.am b/src/Makefile.am index fda612b1ccb0..91c29cfbe52e 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -25,7 +25,7 @@ SUBDIRS = test AM_CPPFLAGS = -I${top_srcdir} -I${top_srcdir}/lib -I${top_srcdir}/src/libev -I${top_srcdir}/auparse -I${top_srcdir}/audisp -I${top_srcdir}/common sbin_PROGRAMS = auditd auditctl aureport ausearch autrace AM_CFLAGS = -D_GNU_SOURCE -Wno-pointer-sign -noinst_HEADERS = auditd-config.h auditd-event.h auditd-listen.h ausearch-llist.h ausearch-options.h auditctl-llist.h aureport-options.h ausearch-parse.h aureport-scan.h ausearch-lookup.h ausearch-int.h auditd-dispatch.h ausearch-string.h ausearch-nvpair.h ausearch-common.h ausearch-avc.h ausearch-time.h ausearch-lol.h auditctl-listing.h ausearch-checkpt.h +noinst_HEADERS = auditd-config.h auditd-event.h auditd-listen.h ausearch-llist.h ausearch-options.h auditctl-llist.h aureport-options.h ausearch-parse.h aureport-scan.h ausearch-lookup.h ausearch-int.h auditd-dispatch.h ausearch-string.h ausearch-nvpair.h ausearch-common.h ausearch-avc.h ausearch-time.h ausearch-lol.h auditctl-listing.h ausearch-checkpt.h ausearch-contid.h auditd_SOURCES = auditd.c auditd-event.c auditd-config.c auditd-reconfig.c auditd-sendmail.c auditd-dispatch.c if ENABLE_LISTENER @@ -41,10 +41,10 @@ auditctl_CFLAGS = -fPIE -DPIE -g -D_GNU_SOURCE auditctl_LDFLAGS = -pie -Wl,-z,relro -Wl,-z,now auditctl_LDADD = -L${top_builddir}/lib -laudit -L${top_builddir}/auparse -lauparse -L${top_builddir}/common -laucommon -aureport_SOURCES = aureport.c auditd-config.c ausearch-llist.c aureport-options.c ausearch-string.c ausearch-parse.c aureport-scan.c aureport-output.c ausearch-lookup.c ausearch-int.c ausearch-time.c ausearch-nvpair.c ausearch-avc.c ausearch-lol.c +aureport_SOURCES = aureport.c auditd-config.c ausearch-llist.c aureport-options.c ausearch-string.c ausearch-parse.c aureport-scan.c aureport-output.c ausearch-lookup.c ausearch-int.c ausearch-time.c ausearch-nvpair.c ausearch-avc.c ausearch-lol.c ausearch-contid.c aureport_LDADD = -L${top_builddir}/lib -laudit -L${top_builddir}/auparse -lauparse -L${top_builddir}/common -laucommon -ausearch_SOURCES = ausearch.c auditd-config.c ausearch-llist.c ausearch-options.c ausearch-report.c ausearch-match.c ausearch-string.c ausearch-parse.c ausearch-int.c ausearch-time.c ausearch-nvpair.c ausearch-lookup.c ausearch-avc.c ausearch-lol.c ausearch-checkpt.c +ausearch_SOURCES = ausearch.c auditd-config.c ausearch-llist.c ausearch-options.c ausearch-report.c ausearch-match.c ausearch-string.c ausearch-parse.c ausearch-int.c ausearch-time.c ausearch-nvpair.c ausearch-lookup.c ausearch-avc.c ausearch-lol.c ausearch-checkpt.c ausearch-contid.c ausearch_LDADD = -L${top_builddir}/lib -laudit -L${top_builddir}/auparse -lauparse -L${top_builddir}/common -laucommon autrace_SOURCES = autrace.c delete_all.c auditctl-llist.c diff --git a/src/ausearch-contid.c b/src/ausearch-contid.c new file mode 100644 index 000000000000..ad50edb5a29c --- /dev/null +++ b/src/ausearch-contid.c @@ -0,0 +1,171 @@ +/* +* ausearch-contid.c - Minimal linked list library for contid +* adapted from ausearch-string.c +* Copyright (c) 2005,2008,2014,2019 Red Hat Inc., Durham, North Carolina. +* All Rights Reserved. +* +* This software may be freely redistributed and/or modified under the +* terms of the GNU General Public License as published by the Free +* Software Foundation; either version 2, or (at your option) any +* later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; see the file COPYING. If not, write to the +* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor +* Boston, MA 02110-1335, USA. +* +* Authors: +* Steve Grubb <sgrubb@xxxxxxxxxx> +* Richard Guy Briggs <rgb@xxxxxxxxxx> +*/ + +#include "ausearch-contid.h" +#include <stdlib.h> + + +void clist_create(clist *l) +{ + l->head = NULL; + l->cur = NULL; + l->cnt = 0; +} + +void clist_last(clist *l) +{ + register cnode* cur; + + if (l->head == NULL) + return; + + // Try using cur so that we don't have to start at beginnning + if (l->cur) + cur = l->cur; + else + cur = l->head; + + // Loop until no next value + while (cur->next) + cur = cur->next; + l->cur = cur; +} + +cnode *clist_next(clist *l) +{ + if (l->cur == NULL) + return NULL; + l->cur = l->cur->next; + return l->cur; +} + +void clist_append(clist *l, cnode *node) +{ + cnode* newnode; + + newnode = malloc(sizeof(cnode)); + + newnode->id = node->id; + newnode->hits = node->hits; + newnode->next = NULL; + + // Make sure cursor is at the end + clist_last(l); + + // if we are at top, fix this up + if (l->head == NULL) + l->head = newnode; + else // Otherwise add pointer to newnode + l->cur->next = newnode; + + // make newnode current + l->cur = newnode; + l->cnt++; +} + +void clist_clear(clist* l) +{ + cnode* nextnode; + register cnode* current; + + current = l->head; + while (current) { + nextnode=current->next; + free(current); + current=nextnode; + } + l->head = NULL; + l->cur = NULL; + l->cnt = 0; +} + +/* This function dominates the timing of aureport. Needs to be more efficient */ +int clist_add_if_uniq(clist *l, const unsigned long long id) +{ + cnode cn; + register cnode *cur; + + if (id == (unsigned long long)-1) + return -1; + + cur = l->head; + while (cur) { + if (id == cur->id) { + cur->hits++; + l->cur = cur; + return 0; + } else + cur = cur->next; + } + + /* No matches, append to the end */ + cn.id = id; + cn.hits = 1; + clist_append(l, &cn); + return 1; +} + +// If lprev would be NULL, use l->head +static void swap_nodes(cnode *lprev, cnode *left, cnode *right) +{ + cnode *t = right->next; + if (lprev) + lprev->next = right; + right->next = left; + left->next = t; +} + +// This will sort the list from most hits to least +void clist_sort_by_hits(clist *l) +{ + register cnode* cur, *prev; + + if (l->cnt <= 1) + return; + + prev = cur = l->head; + + while (cur && cur->next) { + /* If the next node is bigger */ + if (cur->hits < cur->next->hits) { + if (cur == l->head) { + // Update the actual list head + l->head = cur->next; + prev = NULL; + } + swap_nodes(prev, cur, cur->next); + + // start over + prev = cur = l->head; + continue; + } + prev = cur; + cur = cur->next; + } + // End with cur pointing at first record + l->cur = l->head; +} + diff --git a/src/ausearch-contid.h b/src/ausearch-contid.h new file mode 100644 index 000000000000..d728791d3a56 --- /dev/null +++ b/src/ausearch-contid.h @@ -0,0 +1,61 @@ +/* +* ausearch-contid.h - Header file for ausearch-contid.c +* adapted from ausearch-string.h +* Copyright (c) 2005,2008,2019 Red Hat Inc., Durham, North Carolina. +* All Rights Reserved. +* +* This software may be freely redistributed and/or modified under the +* terms of the GNU General Public License as published by the Free +* Software Foundation; either version 2, or (at your option) any +* later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; see the file COPYING. If not, write to the +* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor +* Boston, MA 02110-1335, USA. +* +* Authors: +* Steve Grubb <sgrubb@xxxxxxxxxx> +* Richard Guy Briggs <rgb@xxxxxxxxxx> +*/ + +#ifndef AUCONTID_HEADER +#define AUCONTID_HEADER + +#include "config.h" + +/* This is the node of the linked list. message & item are the only elements + * at this time. Any data elements that are per item goes here. */ +typedef struct _cnode{ + unsigned long long id; // The audit container id + unsigned int hits; // Number of times this contid was attempted to be added + struct _cnode* next; // Next contid node pointer +} cnode; + +/* This is the linked list head. Only data elements that are 1 per + * event goes here. */ +typedef struct { + cnode *head; // List head + cnode *cur; // Pointer to current node + unsigned int cnt; // How many items in this list +} clist; + +void clist_create(clist *l); +static inline void clist_first(clist *l) { l->cur = l->head; } +void clist_last(clist *l); +cnode *clist_next(clist *l); +static inline cnode *clist_get_cur(clist *l) { return l->cur; } +void clist_append(clist *l, cnode *node); +void clist_clear(clist* l); + +/* append a contid if its not already on the list */ +int clist_add_if_uniq(clist *l, const unsigned long long id); +void clist_sort_by_hits(clist *l); + +#endif + diff --git a/src/ausearch-llist.c b/src/ausearch-llist.c index 525ddf67464b..6624398a1b5c 100644 --- a/src/ausearch-llist.c +++ b/src/ausearch-llist.c @@ -213,7 +213,7 @@ void list_clear(llist* l) l->s.syscall = 0; l->s.session_id = -2; if (l->s.contid) { - slist_clear(l->s.contid); + clist_clear(l->s.contid); free(l->s.contid); l->s.contid = NULL; } diff --git a/src/ausearch-llist.h b/src/ausearch-llist.h index c652b4ca06c0..f2f004b09630 100644 --- a/src/ausearch-llist.h +++ b/src/ausearch-llist.h @@ -31,6 +31,7 @@ #include <sys/types.h> #include "ausearch-string.h" #include "ausearch-avc.h" +#include "ausearch-contid.h" #include "ausearch-common.h" @@ -56,7 +57,7 @@ typedef struct int arch; // arch int syscall; // syscall uint32_t session_id; // Login session id - slist *contid; // Container id + clist *contid; // Container id long long exit; // Syscall exit code int exit_is_set; // Syscall exit code is valid char *hostname; // remote hostname diff --git a/src/ausearch-match.c b/src/ausearch-match.c index ae03b670b762..1aa6503e59c2 100644 --- a/src/ausearch-match.c +++ b/src/ausearch-match.c @@ -424,32 +424,28 @@ static int context_match(llist *l) static int contid_match(llist *l) { if (event_contid) { - int found = 0; - const snode *ecn; - slist *ecptr = event_contid; + const cnode *ecn; + clist *ecptr = event_contid; - slist_first(ecptr); - ecn = slist_get_cur(ecptr); + clist_first(ecptr); + ecn = clist_get_cur(ecptr); if (l->s.contid) { - while (ecn && !found) { - const snode *sn; - slist *sptr = l->s.contid; + while (ecn) { + const cnode *cn; + clist *cptr = l->s.contid; - slist_first(sptr); - sn = slist_get_cur(sptr); - while (sn && !found) { - if (!strcmp(sn->str, ecn->str)) - found++; - else - sn = slist_next(sptr); + clist_first(cptr); + cn = clist_get_cur(cptr); + while (cn) { + if (cn->id == ecn->id) + return 1; + cn = clist_next(cptr); } - if (found) - return found; - ecn = slist_next(ecptr); + ecn = clist_next(ecptr); } - return found; } + return 0; } - return 0; + return 1; } diff --git a/src/ausearch-options.c b/src/ausearch-options.c index f4d0f308eddb..1536b5c7ab42 100644 --- a/src/ausearch-options.c +++ b/src/ausearch-options.c @@ -60,7 +60,7 @@ int event_syscall = -1, event_machine = -1; int event_ua = 0, event_ga = 0, event_se = 0; int just_one = 0; uint32_t event_session_id = -2; -const char *event_contid = NULL; +clist *event_contid = NULL; long long event_exit = 0; int event_exit_is_set = 0; int line_buffered = 0; @@ -1201,6 +1201,7 @@ int check_params(int count, char *vars[]) size_t len = strlen(optarg); if (isdigit(optarg[0])) { __u64 contid; + cnode cn; errno = 0; contid = strtoull(optarg,NULL,0); @@ -1211,21 +1212,21 @@ int check_params(int count, char *vars[]) retval = -1; } else { if (!event_contid) { - event_contid = malloc(sizeof(slist)); + event_contid = malloc(sizeof(clist)); if (!event_contid) { retval = -1; break; } - slist_create(event_contid); + clist_create(event_contid); } - sn.str = strdup(optarg); - sn.key = NULL; - sn.hits = 0; - slist_append(event_contid, &sn); + cn.id = contid; + cn.hits = 0; + clist_append(event_contid, &cn); } } else if (len >= 2 && *(optarg)=='-' && (isdigit(optarg[1]))) { __u64 contid; + cnode cn; errno = 0; contid = strtoll(optarg, NULL, 0); @@ -1235,17 +1236,16 @@ int check_params(int count, char *vars[]) optarg); } else { if (!event_contid) { - event_contid = malloc(sizeof(slist)); + event_contid = malloc(sizeof(clist)); if (!event_contid) { retval = -1; break; } - slist_create(event_contid); + clist_create(event_contid); } - sn.str = strdup(optarg); - sn.key = NULL; - sn.hits = 0; - slist_append(event_contid, &sn); + cn.id = contid; + cn.hits = 0; + clist_append(event_contid, &cn); } } else { fprintf(stderr, diff --git a/src/ausearch-options.h b/src/ausearch-options.h index a49d2400ff0d..ac4f97d00a83 100644 --- a/src/ausearch-options.h +++ b/src/ausearch-options.h @@ -29,6 +29,7 @@ #include <stdint.h> #include "ausearch-common.h" #include "ausearch-int.h" +#include "ausearch-contid.h" /* Global variables that describe what search is to be performed */ extern const char *event_key; @@ -40,7 +41,7 @@ extern int line_buffered; extern int event_debug; extern pid_t event_ppid; extern uint32_t event_session_id; -extern const char *event_contid; +extern clist *event_contid; extern ilist *event_type; /* Data type to govern output format */ diff --git a/src/ausearch-parse.c b/src/ausearch-parse.c index 1b58bbc05a57..0949024e680f 100644 --- a/src/ausearch-parse.c +++ b/src/ausearch-parse.c @@ -81,10 +81,10 @@ static int audit_contid_init(search_items *s) { if (s->contid == NULL) { //create - s->contid = malloc(sizeof(slist)); + s->contid = malloc(sizeof(clist)); if (s->contid == NULL) return -1; - slist_create(s->contid); + clist_create(s->contid); } return 0; } @@ -1471,24 +1471,8 @@ static int parse_container_op(const lnode *n, search_items *s) // skip op // skip opid // get contid -/* - if (event_contid != -1) { - str = strstr(term, "contid="); - if (str == NULL) - return 46; - ptr = str + 7; - term = strchr(ptr, ' '); - if (term == NULL) - return 47; - *term = 0; - errno = 0; - s->contid = strtoull(ptr, NULL, 10); - if (errno) - return 48; - *term = ' '; - */ if (event_contid) { - snode sn; + cnode cn; char *comma, *carrat; str = strstr(term, "contid="); @@ -1498,21 +1482,18 @@ static int parse_container_op(const lnode *n, search_items *s) return 48; str += 7; term = strchr(str, ' '); - if (term == NULL) + if (!term) return 47; *term = 0; - sn.str = strdup(str); - sn.key = NULL; - sn.hits = 1; - slist_append(s->contid, &sn); + cn.id = strtoull(str, NULL, 10); + cn.hits = 1; + clist_append(s->contid, &cn); if (term) *term = ' '; // old-contid str = strstr(term, "old-contid="); if (!str) - return 46; - if (audit_contid_init(s) < 0) - return 48; + return 49; str += 11; term = strchr(str, ' '); if (term) @@ -1525,11 +1506,9 @@ static int parse_container_op(const lnode *n, search_items *s) if (carrat) *carrat = 0; do { - sn.str = strdup(str); - sn.key = NULL; - sn.hits = 1; - slist_append(s->contid, &sn); - + cn.id = strtoull(str, NULL, 10); + cn.hits = 1; + clist_append(s->contid, &cn); if (carrat) { str = carrat + 1; *carrat = '^'; @@ -1553,63 +1532,45 @@ static int parse_container_id(const lnode *n, search_items *s) char *ptr, *str, *term = n->message; // get contid -/* - if (event_contid != -1) { + if (event_contid) { + cnode cn; + char *comma, *carrat; + str = strstr(term, "contid="); - if (str == NULL) - return 49; - ptr = str + 7; - term = strchr(ptr, ' '); - if (term) + if (!str) return 50; - *term = 0; - errno = 0; - s->contid = strtoull(ptr, NULL, 10); - if (errno) + if (audit_contid_init(s) < 0) return 51; - *term = ' '; - */ - if (event_contid) { - str = strstr(term, "contid="); - if (str) { - snode sn; - char *comma, *carrat; - - if (audit_contid_init(s) < 0) - return 50; - str += 7; - term = strchr(str, ' '); - if (term) - *term = 0; - comma = strchr(str, ','); - if (comma) - *comma = 0; + str += 7; + term = strchr(str, ' '); + if (term) + *term = 0; + comma = strchr(str, ','); + if (comma) + *comma = 0; + do { + carrat = strchr(str, '^'); + if (carrat) + *carrat = 0; do { - carrat = strchr(str, '^'); - if (carrat) - *carrat = 0; - do { - sn.str = strdup(str); - sn.key = NULL; - sn.hits = 1; - slist_append(s->contid, &sn); + cn.id = strtoull(str, NULL, 10); + cn.hits = 1; + clist_append(s->contid, &cn); - if (carrat) { - str = carrat + 1; - *carrat = '^'; - carrat = strchr(str, '^'); - } - } while (carrat); - if (comma) { - str = comma + 1; - *comma = ','; - comma = strchr(str, ','); + if (carrat) { + str = carrat + 1; + *carrat = '^'; + carrat = strchr(str, '^'); } - } while (comma); - if (term) - *term = ' '; - } else - return 49; + } while (carrat); + if (comma) { + str = comma + 1; + *comma = ','; + comma = strchr(str, ','); + } + } while (comma); + if (term) + *term = ' '; } return 0; } -- 1.8.3.1 _______________________________________________ Containers mailing list Containers@xxxxxxxxxxxxxxxxxxxxxxxxxx https://lists.linuxfoundation.org/mailman/listinfo/containers