From 42d79281027ce958c1f3f3d901a76fde64517faafa52f9e32c23a655d8808b85 Mon Sep 17 00:00:00 2001 From: Tony Jones Date: Thu, 29 Jan 2015 19:21:15 +0000 Subject: [PATCH 1/4] Accepting request 283367 from home:fdmanana:branches:security - Teach ausearch to filter AppArmor events (Fate#317726). Added patch file audit-ausearch-filter-apparmor-events.patch OBS-URL: https://build.opensuse.org/request/show/283367 OBS-URL: https://build.opensuse.org/package/show/security/audit?expand=0&rev=76 --- audit-ausearch-filter-apparmor-events.patch | 1490 +++++++++++++++++++ audit-secondary.spec | 4 +- audit.changes | 6 + audit.spec | 2 +- 4 files changed, 1500 insertions(+), 2 deletions(-) create mode 100644 audit-ausearch-filter-apparmor-events.patch diff --git a/audit-ausearch-filter-apparmor-events.patch b/audit-ausearch-filter-apparmor-events.patch new file mode 100644 index 0000000..1fc12af --- /dev/null +++ b/audit-ausearch-filter-apparmor-events.patch @@ -0,0 +1,1490 @@ +From: Filipe Manana +Date: Wed, 28 Jan 2015 16:08:01 +0000 +References: Fate#317726 +Upstream: never +Subject: [PATCH] Teach ausearch to filter AppArmor events + +This changes makes ausearch able to filter AppArmor events according +to its specific fields. Several new command line parameters allow to +filter events by specific values, whose key matches the command line +parameters' names. These new parameters are: + + --apparmor + --operation + --profile + --parent + --requested_mask + --denied_mask + --fsuid + --ouid + --target + --info + --capname + --error + --namespace + --rlimit + --laddr + --faddr + --lport + --fport + --family + --sock_type + --protocol + +Usage examples: + + $ ausearch -if log.txt --apparmor DENIED + ---- + time->Mon Jan 19 20:08:24 2015 + type=1400 audit(1421698104.388:45): apparmor="DENIED" operation="open" parent=2442 profile="/usr/bin/xchat" name="/dev/shm/pulse-shm-1760669882" pid=2934 comm="xchat" + requested_mask="r" denied_mask="r" fsuid=1000 ouid=1000 + ---- + time->Mon Jan 19 20:08:24 2015 + type=1400 audit(1421698104.388:47): apparmor="DENIED" operation="mknod" parent=2442 profile="/usr/bin/xchat" name="/dev/shm/pulse-shm-1001794793" pid=2934 comm="xchat" + requested_mask="c" denied_mask="c" fsuid=1000 ouid=1000 + + $ ausearch -if log.txt --apparmor DENIED --operation mknod + ---- + time->Mon Jan 19 20:08:24 2015 + type=1400 audit(1421698104.388:47): apparmor="DENIED" operation="mknod" parent=2442 profile="/usr/bin/xchat" name="/dev/shm/pulse-shm-1001794793" pid=2934 comm="xchat" + requested_mask="c" denied_mask="c" fsuid=1000 ouid=1000 + + $ ausearch -if log.txt --comm xchat --fport 6697 + ---- + time->Sun Jan 18 18:37:45 2015 + type=1400 audit(1421606265.719:2082): apparmor="ALLOWED" operation="recvmsg" parent=2391 profile="/usr/bin/xchat" pid=4107 comm="xchat" laddr=10.163.0.243 lport=55184 + faddr=149.44.176.29 fport=6697 family="inet" sock_type="stream" protocol=6 + ---- + time->Sun Jan 18 18:37:46 2015 + type=1400 audit(1421606266.203:2098): apparmor="ALLOWED" operation="sendmsg" parent=2391 profile="/usr/bin/xchat" pid=4107 comm="xchat" laddr=10.163.0.243 lport=55184 + faddr=149.44.176.29 fport=6697 family="inet" sock_type="stream" protocol=6 + ---- + time->Sun Jan 18 18:37:46 2015 + type=1400 audit(1421606266.259:2101): apparmor="ALLOWED" operation="recvmsg" parent=2391 profile="/usr/bin/xchat" pid=4107 comm="xchat" laddr=10.163.0.243 lport=55184 + faddr=149.44.176.29 fport=6697 family="inet" sock_type="stream" protocol=6 + ---- + time->Sun Jan 18 18:37:48 2015 + type=1400 audit(1421606268.207:2104): apparmor="ALLOWED" operation="sendmsg" parent=2391 profile="/usr/bin/xchat" pid=4107 comm="xchat" laddr=10.163.0.243 lport=55184 + faddr=149.44.176.29 fport=6697 family="inet" sock_type="stream" protocol=6 + + $ ausearch -if log.txt --comm xchat --fport 6697 --operation sendmsg + + time->Sun Jan 18 18:37:46 2015 + type=1400 audit(1421606266.203:2098): apparmor="ALLOWED" operation="sendmsg" parent=2391 profile="/usr/bin/xchat" pid=4107 comm="xchat" laddr=10.163.0.243 lport=55184 + faddr=149.44.176.29 fport=6697 family="inet" sock_type="stream" protocol=6 + ---- + time->Sun Jan 18 18:37:48 2015 + type=1400 audit(1421606268.207:2104): apparmor="ALLOWED" operation="sendmsg" parent=2391 profile="/usr/bin/xchat" pid=4107 comm="xchat" laddr=10.163.0.243 lport=55184 + faddr=149.44.176.29 fport=6697 family="inet" sock_type="stream" protocol=6 + +Signed-off-by: Filipe Manana +--- + docs/ausearch.8 | 63 +++++++ + src/aureport-options.c | 23 +++ + src/ausearch-common.h | 23 +++ + src/ausearch-llist.c | 56 ++++++ + src/ausearch-llist.h | 22 +++ + src/ausearch-lol.c | 2 +- + src/ausearch-match.c | 119 +++++++++++++ + src/ausearch-options.c | 404 ++++++++++++++++++++++++++++++++++++++++++- + src/ausearch-parse.c | 459 +++++++++++++++++++++++++++++++++++++++++++++++++ + 9 files changed, 1168 insertions(+), 3 deletions(-) + +diff --git a/docs/ausearch.8 b/docs/ausearch.8 +index 54018ae..c441f7c 100644 +--- a/docs/ausearch.8 ++++ b/docs/ausearch.8 +@@ -18,15 +18,39 @@ Also be aware that not all record types have the requested information. For exam + .BR \-a ,\ \-\-event \ \fIaudit-event-id\fP + Search for an event based on the given \fIevent ID\fP. Messages always start with something like msg=audit(1116360555.329:2401771). The event ID is the number after the ':'. All audit events that are recorded from one application's syscall have the same audit event ID. A second syscall made by the same application will have a different event ID. This way they are unique. + .TP ++.BR \-\-apparmor \ \fItype\fP ++Search for an event matching the given AppArmor \fItype\fP value. This filters events from AppArmor wich have an attribute like apparmor="ALLOWED" for example. ++.TP ++.BR \-\-capname \ \fIcapname\fP ++Search for an event based on the given capability name \fIcapname\fP (AppArmor events). ++.TP + .BR \-c ,\ \-\-comm \ \fIcomm-name\fP + Search for an event based on the given \fIcomm name\fP. The comm name is the executable's name from the task structure. + .TP ++.BR \-\-denied_mask \ \fImask\fP ++Search for an event matching the given denied \fImask\fP (AppArmor events). ++.TP ++.BR \-\-error \ \fIerror\fP ++Search for an event based on the given \fIerror\fP (AppArmor events). ++.TP + .BR \-e,\ \-\-exit \ \fIexit-code-or-errno\fP + Search for an event based on the given syscall \fIexit code or errno\fP. + .TP ++.BR \-\-faddr \ \fIaddress\fP ++Search for an event based on the given foreign \fIaddress\fP (AppArmor events). ++.TP ++.BR \-\-family \ \fIfamily\fP ++Search for an event based on the given network \fIfamily\fP (AppArmor events). ++.TP + .BR \-f ,\ \-\-file \ \fIfile-name\fP + Search for an event based on the given \fIfilename\fP. + .TP ++.BR \-\-fport \ \fIport\fP ++Search for an event based on the given foreign \fport\fP (AppArmor events). ++.TP ++.BR \-\-fsuid \ \fIfsuid\fP ++Search for an event based on the given \fIfsuid\fP (AppArmor events). ++.TP + .BR \-ga ,\ \-\-gid-all \ \fIall-group-id\fP + Search for an event with either effective group ID or group ID matching the given \fIgroup ID\fP. + .TP +@@ -45,6 +69,9 @@ Search for an event with the given \fIhost name\fP. The hostname can be either a + .BR \-i ,\ \-\-interpret + Interpret numeric entities into text. For example, uid is converted to account name. The conversion is done using the current resources of the machine where the search is being run. If you have renamed the accounts, or don't have the same accounts on your machine, you could get misleading results. + .TP ++.BR \-\-info \ \fIinfo\fP ++Search for an event matching the given \fIinfo\fP value (AppArmor events). ++.TP + .BR \-if ,\ \-\-input \ \fIfile-name\fP + Use the given \fIfile\fP instead of the logs. This is to aid analysis where the logs have been moved to another machine or only part of a log was saved. + .TP +@@ -57,27 +84,57 @@ Stop after emitting the first event that matches the search criteria. + .BR \-k ,\ \-\-key \ \fIkey-string\fP + Search for an event based on the given \fIkey string\fP. + .TP ++.BR \-\-laddr \ \fIaddress\fP ++Search for an event based on the given local \fIaddress\fP (AppArmor events). ++.TP + .BR \-l ,\ \-\-line-buffered + Flush output on every line. Most useful when stdout is connected to a pipe and the default block buffering strategy is undesirable. May impose a performance penalty. + .TP ++.BR \-\-lport \ \fIport\fP ++Search for an event based on the given local \fport\fP (AppArmor events). ++.TP + .BR \-m ,\ \-\-message \ \fImessage-type\fP\ |\ \fIcomma-sep-message-type-list\fP + Search for an event matching the given \fImessage type\fP. You may also enter a \fIcomma separated list of message types\fP. There is an \fBALL\fP message type that doesn't exist in the actual logs. It allows you to get all messages in the system. The list of valid messages types is long. The program will display the list whenever no message type is passed with this parameter. The message type can be either text or numeric. If you enter a list, there can be only commas and no spaces separating the list. + .TP ++.BR \-\-namespace \ \fInamespace\fP ++Search for an event matching the given \fInamespace\fP (AppArmor events). ++.TP + .BR \-n ,\ \-\-node \ \fInode-name\fP + Search for events originating from \fInode name\fP string. Multiple nodes are allowed, and if any nodes match, the event is matched. + .TP + .BR \-o ,\ \-\-object \ \fISE-Linux-context-string\fP + Search for event with \fItcontext\fP (object) matching the string. + .TP ++.BR \-\-operation \ \fIoperation\fP ++Search for an event matching the given \fIoperation\fP (AppArmor events). ++.TP ++.BR \-\-ouid \ \fIouid\fP ++Search for an event based on the given \fIouid\fP (AppArmor events). ++.TP + .BR \-p ,\ \-\-pid \ \fIprocess-id\fP + Search for an event matching the given \fIprocess ID\fP. + .TP + .BR \-pp ,\ \-\-ppid \ \fIparent-process-id\fP + Search for an event matching the given \fIparent process ID\fP. + .TP ++.BR \-\-parent \ \fIparent\fP ++Search for an event matching the given \fIparent\fP (AppArmor events). ++.TP ++.BR \-\-profile \ \fIprofile\fP ++Search for an event matching the given \fIprofile\fP (AppArmor events). ++.TP ++.BR \-\-protocol \ \fIprotocol\fP ++Search for an event matching the given \fIprotocol\fP (AppArmor events). ++.TP + .BR \-r ,\ \-\-raw + Output is completely unformatted. This is useful for extracting records that can still be interpreted by audit tools. + .TP ++.BR \-\-requested_mask \ \fImask\fP ++Search for an event matching the given requested \fImask\fP (AppArmor events). ++.TP ++.BR \-\-rlimit \ \fIrlimit\fP ++Search for an event matching the given \fIrlimit\fP (AppArmor events). ++.TP + .BR \-sc ,\ \-\-syscall \ \fIsyscall-name-or-value\fP + Search for an event matching the given \fIsyscall\fP. You may either give the numeric syscall value or the syscall name. If you give the syscall name, it will use the syscall table for the machine that you are using. + .TP +@@ -87,6 +144,9 @@ Search for event with either \fIscontext\fP/subject or \fItcontext\fP/object mat + .BR \-\-session \ \fILogin-Session-ID\fP + Search for events matching the given Login Session ID. This process attribute is set when a user logs in and can tie any process to a particular user login. + .TP ++.BR \-\-sock_type \ \fIsocket-type\fP ++Search for an event based on the given \fIsocket-type\fP (AppArmor events). ++.TP + .BR \-su ,\ \-\-subject \ \fISE-Linux-context-string\fP + Search for event with \fIscontext\fP (subject) matching the string. + .TP +@@ -96,6 +156,9 @@ Search for an event matching the given \fIsuccess value\fP. Legal values are + and + .BR no . + .TP ++.BR \-\-target \ \fItarget\fP ++Search for events matching the given \fItarget\fP (AppArmor events). ++.TP + .BR \-te ,\ \-\-end \ [\fIend-date\fP]\ [\fIend-time\fP] + Search for events with time stamps equal to or before the given end time. The format of end time depends on your locale. If the date is omitted, + .B today +diff --git a/src/aureport-options.c b/src/aureport-options.c +index f1ab50a..f5a9ac1 100644 +--- a/src/aureport-options.c ++++ b/src/aureport-options.c +@@ -51,6 +51,29 @@ const char *event_subject = NULL; + const char *event_object = NULL; + int event_exit = 0, event_exit_is_set = 0; + int event_ppid = -1, event_session_id = -2; ++/* AppArmor specific search fields */ ++const char *event_aa_apparmor = NULL; ++const char *event_aa_operation = NULL; ++const char *event_aa_profile = NULL; ++pid_t event_aa_parent = -1; ++const char *event_aa_requested_mask = NULL; ++const char *event_aa_denied_mask = NULL; ++uid_t event_aa_fsuid = -1; ++uid_t event_aa_ouid = -1; ++const char *event_aa_target = NULL; ++const char *event_aa_info = NULL; ++const char *event_aa_capname = NULL; ++long event_aa_error = 0; ++const char *event_aa_namespace = NULL; ++const char *event_aa_rlimit = NULL; ++const char *event_aa_laddr = NULL; ++const char *event_aa_faddr = NULL; ++int event_aa_lport = -1; ++int event_aa_fport = -1; ++const char *event_aa_family = NULL; ++const char *event_aa_sock_type = NULL; ++int event_aa_protocol = -1; ++ + + /* These are used by aureport */ + const char *dummy = "dummy"; +diff --git a/src/ausearch-common.h b/src/ausearch-common.h +index 08b0cba..6509e0a 100644 +--- a/src/ausearch-common.h ++++ b/src/ausearch-common.h +@@ -42,6 +42,29 @@ extern int event_syscall; + extern const char *event_exe; + extern int event_ua, event_ga; + extern int event_exit, event_exit_is_set; ++/* AppArmor search fields. */ ++extern const char *event_aa_apparmor; ++extern const char *event_aa_operation; ++extern const char *event_aa_profile; ++extern pid_t event_aa_parent; ++extern const char *event_aa_requested_mask; ++extern const char *event_aa_denied_mask; ++extern uid_t event_aa_fsuid; ++extern uid_t event_aa_ouid; ++extern const char *event_aa_target; ++extern const char *event_aa_info; ++extern const char *event_aa_capname; ++extern long event_aa_error; ++extern const char *event_aa_namespace; ++extern const char *event_aa_rlimit; ++extern const char *event_aa_laddr; ++extern const char *event_aa_faddr; ++extern int event_aa_lport; ++extern int event_aa_fport; ++extern const char *event_aa_family; ++extern const char *event_aa_sock_type; ++extern int event_aa_protocol; ++ + + typedef enum { F_BOTH, F_FAILED, F_SUCCESS } failed_t; + typedef enum { C_NEITHER, C_ADD, C_DEL } conf_act_t; +diff --git a/src/ausearch-llist.c b/src/ausearch-llist.c +index 32cda7e..9077291 100644 +--- a/src/ausearch-llist.c ++++ b/src/ausearch-llist.c +@@ -57,6 +57,27 @@ void list_create(llist *l) + l->s.session_id = -2; + l->s.exit = 0; + l->s.exit_is_set = 0; ++ l->s.aa_apparmor = NULL; ++ l->s.aa_operation = NULL; ++ l->s.aa_profile = NULL; ++ l->s.aa_parent = -1; ++ l->s.aa_requested_mask = NULL; ++ l->s.aa_denied_mask = NULL; ++ l->s.aa_fsuid = -1; ++ l->s.aa_ouid = -1; ++ l->s.aa_target = NULL; ++ l->s.aa_info = NULL; ++ l->s.aa_capname = NULL; ++ l->s.aa_error = 0; ++ l->s.aa_namespace = NULL; ++ l->s.aa_rlimit = NULL; ++ l->s.aa_laddr = NULL; ++ l->s.aa_faddr = NULL; ++ l->s.aa_lport = -1; ++ l->s.aa_fport = -1; ++ l->s.aa_family = NULL; ++ l->s.aa_sock_type = NULL; ++ l->s.aa_protocol = -1; + } + + void list_last(llist *l) +@@ -199,6 +220,41 @@ void list_clear(llist* l) + l->s.session_id = -2; + l->s.exit = 0; + l->s.exit_is_set = 0; ++ free(l->s.aa_apparmor); ++ l->s.aa_apparmor = NULL; ++ free(l->s.aa_operation); ++ l->s.aa_operation = NULL; ++ free(l->s.aa_profile); ++ l->s.aa_profile = NULL; ++ l->s.aa_parent = -1; ++ free(l->s.aa_requested_mask); ++ l->s.aa_requested_mask = NULL; ++ free(l->s.aa_denied_mask); ++ l->s.aa_denied_mask = NULL; ++ l->s.aa_fsuid = -1; ++ l->s.aa_ouid = -1; ++ free(l->s.aa_target); ++ l->s.aa_target = NULL; ++ free(l->s.aa_info); ++ l->s.aa_info = NULL; ++ free(l->s.aa_capname); ++ l->s.aa_capname = NULL; ++ l->s.aa_error = 0; ++ free(l->s.aa_namespace); ++ l->s.aa_namespace = NULL; ++ free(l->s.aa_rlimit); ++ l->s.aa_rlimit = NULL; ++ free(l->s.aa_laddr); ++ l->s.aa_laddr = NULL; ++ free(l->s.aa_faddr); ++ l->s.aa_faddr = NULL; ++ l->s.aa_lport = -1; ++ l->s.aa_fport = -1; ++ free(l->s.aa_family); ++ l->s.aa_family = NULL; ++ free(l->s.aa_sock_type); ++ l->s.aa_sock_type = NULL; ++ l->s.aa_protocol = -1; + } + + int list_get_event(llist* l, event *e) +diff --git a/src/ausearch-llist.h b/src/ausearch-llist.h +index a77d800..09c7ac6 100644 +--- a/src/ausearch-llist.h ++++ b/src/ausearch-llist.h +@@ -64,6 +64,28 @@ typedef struct + char *comm; // comm name + alist *avc; // avcs for the event + char *acct; // account used when uid is invalid ++ // AppArmor specific fields ++ char *aa_apparmor; // ield apparmor=... ++ char *aa_operation; // field operation=... ++ char *aa_profile; // field profile=... ++ pid_t aa_parent; // field parent=... ++ char *aa_requested_mask; // field requested_mask=... ++ char *aa_denied_mask; // field denied_mask=... ++ uid_t aa_fsuid; // field fsuid=... ++ uid_t aa_ouid; // field ouid=... ++ char *aa_target; // field target=... ++ char *aa_info; // field info=... ++ char *aa_capname; // field capname=... ++ long aa_error; // field error=... ++ char *aa_namespace; // field namespace=... ++ char *aa_rlimit; // field rlimit=... ++ char *aa_laddr; // field laddr=... ++ char *aa_faddr; // field faddr=... ++ int aa_lport; // field lport=... ++ int aa_fport; // field fport=... ++ char *aa_family; // field family=... ++ char *aa_sock_type; // field sock_type=... ++ int aa_protocol; // field protocol=... + } search_items; + + /* This is the node of the linked list. Any data elements that are per +diff --git a/src/ausearch-lol.c b/src/ausearch-lol.c +index c291f5f..12b4a95 100644 +--- a/src/ausearch-lol.c ++++ b/src/ausearch-lol.c +@@ -28,7 +28,7 @@ + #include + #include "ausearch-common.h" + +-#define ARRAY_LIMIT 80 ++#define ARRAY_LIMIT 8192 + static int ready = 0; + + void lol_create(lol *lo) +diff --git a/src/ausearch-match.c b/src/ausearch-match.c +index 24b9320..f78e705 100644 +--- a/src/ausearch-match.c ++++ b/src/ausearch-match.c +@@ -201,6 +201,125 @@ int match(llist *l) + return 0; + } + } ++ if (event_aa_apparmor) { ++ if (l->s.aa_apparmor == NULL) ++ return 0; ++ if (strmatch(event_aa_apparmor, ++ l->s.aa_apparmor) == 0) ++ return 0; ++ } ++ if (event_aa_operation) { ++ if (l->s.aa_operation == NULL) ++ return 0; ++ if (strmatch(event_aa_operation, ++ l->s.aa_operation) == 0) ++ return 0; ++ } ++ if (event_aa_profile) { ++ if (l->s.aa_profile == NULL) ++ return 0; ++ if (strmatch(event_aa_profile, ++ l->s.aa_profile) == 0) ++ return 0; ++ } ++ if ((event_aa_parent != -1) && ++ (event_aa_parent != l->s.aa_parent)) ++ return 0; ++ if (event_aa_requested_mask) { ++ if (l->s.aa_requested_mask == NULL) ++ return 0; ++ if (strmatch(event_aa_requested_mask, ++ l->s.aa_requested_mask) == 0) ++ return 0; ++ } ++ if (event_aa_denied_mask) { ++ if (l->s.aa_denied_mask == NULL) ++ return 0; ++ if (strmatch(event_aa_denied_mask, ++ l->s.aa_denied_mask) == 0) ++ return 0; ++ } ++ if ((event_aa_fsuid != -1) && ++ (event_aa_fsuid != l->s.aa_fsuid)) ++ return 0; ++ if ((event_aa_ouid != -1) && ++ (event_aa_ouid != l->s.aa_ouid)) ++ return 0; ++ if (event_aa_target) { ++ if (l->s.aa_target == NULL) ++ return 0; ++ if (strmatch(event_aa_target, ++ l->s.aa_target) == 0) ++ return 0; ++ } ++ if (event_aa_info) { ++ if (l->s.aa_info == NULL) ++ return 0; ++ if (strmatch(event_aa_info, ++ l->s.aa_info) == 0) ++ return 0; ++ } ++ if (event_aa_capname) { ++ if (l->s.aa_capname == NULL) ++ return 0; ++ if (strmatch(event_aa_capname, ++ l->s.aa_capname) == 0) ++ return 0; ++ } ++ if ((event_aa_error != 0) && ++ (event_aa_error != l->s.aa_error)) ++ return 0; ++ if (event_aa_namespace) { ++ if (l->s.aa_namespace == NULL) ++ return 0; ++ if (strmatch(event_aa_namespace, ++ l->s.aa_namespace) == 0) ++ return 0; ++ } ++ if (event_aa_rlimit) { ++ if (l->s.aa_rlimit == NULL) ++ return 0; ++ if (strmatch(event_aa_rlimit, ++ l->s.aa_rlimit) == 0) ++ return 0; ++ } ++ if (event_aa_laddr) { ++ if (l->s.aa_laddr == NULL) ++ return 0; ++ if (strmatch(event_aa_laddr, ++ l->s.aa_laddr) == 0) ++ return 0; ++ } ++ if (event_aa_faddr) { ++ if (l->s.aa_faddr == NULL) ++ return 0; ++ if (strmatch(event_aa_faddr, ++ l->s.aa_faddr) == 0) ++ return 0; ++ } ++ if ((event_aa_lport != -1) && ++ (event_aa_lport != l->s.aa_lport)) ++ return 0; ++ if ((event_aa_fport != -1) && ++ (event_aa_fport != l->s.aa_fport)) ++ return 0; ++ if (event_aa_family) { ++ if (l->s.aa_family == NULL) ++ return 0; ++ if (strmatch(event_aa_family, ++ l->s.aa_family) == 0) ++ return 0; ++ } ++ if (event_aa_sock_type) { ++ if (l->s.aa_sock_type == NULL) ++ return 0; ++ if (strmatch(event_aa_sock_type, ++ l->s.aa_sock_type) == 0) ++ return 0; ++ } ++ if ((event_aa_protocol != -1) && ++ (event_aa_protocol != l->s.aa_protocol)) ++ return 0; + if (context_match(l) == 0) + return 0; + return 1; +diff --git a/src/ausearch-options.c b/src/ausearch-options.c +index 8f4b64e..4e66771 100644 +--- a/src/ausearch-options.c ++++ b/src/ausearch-options.c +@@ -63,6 +63,28 @@ const char *event_subject = NULL; + const char *event_object = NULL; + report_t report_format = RPT_DEFAULT; + ilist *event_type; ++/* AppArmor specific search fields */ ++const char *event_aa_apparmor = NULL; ++const char *event_aa_operation = NULL; ++const char *event_aa_profile = NULL; ++pid_t event_aa_parent = -1; ++const char *event_aa_requested_mask = NULL; ++const char *event_aa_denied_mask = NULL; ++uid_t event_aa_fsuid = -1; ++uid_t event_aa_ouid = -1; ++const char *event_aa_target = NULL; ++const char *event_aa_info = NULL; ++const char *event_aa_capname = NULL; ++long event_aa_error = 0; ++const char *event_aa_namespace = NULL; ++const char *event_aa_rlimit = NULL; ++const char *event_aa_laddr = NULL; ++const char *event_aa_faddr = NULL; ++int event_aa_lport = -1; ++int event_aa_fport = -1; ++const char *event_aa_family = NULL; ++const char *event_aa_sock_type = NULL; ++int event_aa_protocol = -1; + + const slist *event_node_list = NULL; + +@@ -77,7 +99,13 @@ S_HOSTNAME, S_INTERP, S_INFILE, S_MESSAGE_TYPE, S_PID, S_SYSCALL, S_OSUCCESS, + S_TIME_END, S_TIME_START, S_TERMINAL, S_ALL_UID, S_EFF_UID, S_UID, S_LOGINID, + S_VERSION, S_EXACT_MATCH, S_EXECUTABLE, S_CONTEXT, S_SUBJECT, S_OBJECT, + S_PPID, S_KEY, S_RAW, S_NODE, S_IN_LOGS, S_JUST_ONE, S_SESSION, S_EXIT, +-S_LINEBUFFERED }; ++S_LINEBUFFERED, ++/* AppArmor specific search options. */ ++S_AA_APPARMOR, S_AA_OPERATION, S_AA_PROFILE, S_AA_PARENT, ++S_AA_REQUESTED_MASK, S_AA_DENIED_MASK, S_AA_FSUID, S_AA_OUID, ++S_AA_TARGET, S_AA_INFO, S_AA_CAPNAME, S_AA_ERROR, S_AA_NAMESPACE, ++S_AA_RLIMIT, S_AA_LADDR, S_AA_FADDR, S_AA_LPORT, S_AA_FPORT, ++S_AA_FAMILY, S_AA_SOCK_TYPE, S_AA_PROTOCOL }; + + static struct nv_pair optiontab[] = { + { S_EVENT, "-a" }, +@@ -148,7 +176,29 @@ static struct nv_pair optiontab[] = { + { S_EXACT_MATCH, "-w" }, + { S_EXACT_MATCH, "--word" }, + { S_EXECUTABLE, "-x" }, +- { S_EXECUTABLE, "--executable" } ++ { S_EXECUTABLE, "--executable" }, ++ /* AppArmor specific search fields. */ ++ { S_AA_APPARMOR, "--apparmor" }, ++ { S_AA_OPERATION, "--operation" }, ++ { S_AA_PROFILE, "--profile" }, ++ { S_AA_PARENT, "--parent" }, ++ { S_AA_REQUESTED_MASK, "--requested_mask" }, ++ { S_AA_DENIED_MASK, "--denied_mask" }, ++ { S_AA_FSUID, "--fsuid" }, ++ { S_AA_OUID, "--ouid" }, ++ { S_AA_TARGET, "--target" }, ++ { S_AA_INFO, "--info" }, ++ { S_AA_CAPNAME, "--capname" }, ++ { S_AA_ERROR, "--error" }, ++ { S_AA_NAMESPACE, "--namespace" }, ++ { S_AA_RLIMIT, "--rlimit" }, ++ { S_AA_LADDR, "--laddr" }, ++ { S_AA_FADDR, "--faddr" }, ++ { S_AA_LPORT, "--lport" }, ++ { S_AA_FPORT, "--fport" }, ++ { S_AA_FAMILY, "--family" }, ++ { S_AA_SOCK_TYPE, "--sock_type" }, ++ { S_AA_PROTOCOL, "--protocol" }, + }; + #define OPTION_NAMES (sizeof(optiontab)/sizeof(optiontab[0])) + +@@ -167,9 +217,17 @@ static void usage(void) + { + printf("usage: ausearch [options]\n" + "\t-a,--event \tsearch based on audit event id\n" ++ "\t--apparmor \tsearch based on AppArmor type\n" ++ "\t--capname \tsearch based on capability name (AppArmor events)\n" + "\t-c,--comm \t\tsearch based on command line name\n" ++ "\t--denied_mask \t\tsearch based on denied mask (AppArmor events)\n" ++ "\t--error \tsearch based on error value (AppArmor events)\n" + "\t-e,--exit \tsearch based on syscall exit code\n" ++ "\t--faddr
\tsearch based on foreign address (AppArmor events)\n" ++ "\t--family \tsearch based on network family (AppArmor events)\n" + "\t-f,--file \t\tsearch based on file name\n" ++ "\t--fport \tsearch based on foreign port (AppArmor events)\n" ++ "\t--fsuid \t\tsearch based on fsuid (AppArmor events)\n" + "\t-ga,--gid-all \tsearch based on All group ids\n" + "\t-ge,--gid-effective search based on Effective\n\t\t\t\t\tgroup id\n" + "\t-gi,--gid \t\tsearch based on group id\n" +@@ -177,21 +235,34 @@ static void usage(void) + "\t-hn,--host \t\tsearch based on remote host name\n" + "\t-i,--interpret\t\t\tInterpret results to be human readable\n" + "\t-if,--input \tuse this file instead of current logs\n" ++ "\t--info \tsearch based on requested info (AppArmor events)\n" + "\t--input-logs\t\t\tUse the logs even if stdin is a pipe\n" + "\t--just-one\t\t\tEmit just one event\n" + "\t-k,--key \t\tsearch based on key field\n" ++ "\t--laddr
\tsearch based on local address (AppArmor events)\n" + "\t-l, --line-buffered\t\tFlush output on every line\n" ++ "\t--lport \tsearch based on local port (AppArmor events)\n" + "\t-m,--message \tsearch based on message type\n" ++ "\t--namespace \tsearch based on namespace (AppArmor events)\n" + "\t-n,--node \t\tsearch based on machine's name\n" + "\t-o,--object search based on context of object\n" ++ "\t--operation search based on operation (AppArmor events)\n" ++ "\t--ouid search based on ouid (AppArmor events)\n" + "\t-p,--pid \t\tsearch based on process id\n" + "\t-pp,--ppid \tsearch based on parent process id\n" ++ "\t--parent \tsearch based on parent (AppArmor events)\n" ++ "\t--profile \tsearch based on profile (AppArmor events)\n" ++ "\t--protocol \tsearch based on protocol (AppArmor events)\n" + "\t-r,--raw\t\t\toutput is completely unformatted\n" ++ "\t--requested_mask \tsearch based on requested mask (AppArmor events)\n" ++ "\t--rlimit \tsearch based on rlimit (AppArmor events)\n" + "\t-sc,--syscall \tsearch based on syscall name or number\n" + "\t-se,--context search based on either subject or\n\t\t\t\t\t object\n" + "\t--session \tsearch based on login session id\n" ++ "\t--sock_type search based on socket type (AppArmor events)\n" + "\t-su,--subject search based on context of the Subject\n" + "\t-sv,--success \tsearch based on syscall or event\n\t\t\t\t\tsuccess value\n" ++ "\t--target search based on target (AppArmor events)\n" + "\t-te,--end [end date] [end time]\tending date & time for search\n" + "\t-ts,--start [start date] [start time]\tstarting data & time for search\n" + "\t-tm,--terminal \tsearch based on terminal\n" +@@ -1026,6 +1097,335 @@ int check_params(int count, char *vars[]) + case S_LINEBUFFERED: + line_buffered = 1; + break; ++ case S_AA_APPARMOR: ++ if (!optarg) { ++ fprintf(stderr, ++ "Argument is required for %s\n", ++ vars[c]); ++ retval = -1; ++ } else { ++ event_aa_apparmor = strdup(optarg); ++ if (event_aa_apparmor == NULL) ++ retval = -1; ++ c++; ++ } ++ break; ++ case S_AA_OPERATION: ++ if (!optarg) { ++ fprintf(stderr, ++ "Argument is required for %s\n", ++ vars[c]); ++ retval = -1; ++ } else { ++ event_aa_operation = strdup(optarg); ++ if (event_aa_operation == NULL) ++ retval = -1; ++ c++; ++ } ++ break; ++ case S_AA_PROFILE: ++ if (!optarg) { ++ fprintf(stderr, ++ "Argument is required for %s\n", ++ vars[c]); ++ retval = -1; ++ } else { ++ event_aa_profile = strdup(optarg); ++ if (event_aa_profile == NULL) ++ retval = -1; ++ c++; ++ } ++ break; ++ case S_AA_PARENT: ++ if (!optarg) { ++ fprintf(stderr, ++ "Argument is required for %s\n", ++ vars[c]); ++ retval = -1; ++ break; ++ } ++ if (isdigit(optarg[0])) { ++ errno = 0; ++ event_aa_parent = strtol(optarg, NULL, 10); ++ if (errno) ++ retval = -1; ++ c++; ++ } else { ++ fprintf(stderr, ++ "Parent must be a numeric value, was %s\n", ++ optarg); ++ retval = -1; ++ } ++ break; ++ case S_AA_REQUESTED_MASK: ++ if (!optarg) { ++ fprintf(stderr, ++ "Argument is required for %s\n", ++ vars[c]); ++ retval = -1; ++ } else { ++ event_aa_requested_mask = strdup(optarg); ++ if (event_aa_requested_mask == NULL) ++ retval = -1; ++ c++; ++ } ++ break; ++ case S_AA_DENIED_MASK: ++ if (!optarg) { ++ fprintf(stderr, ++ "Argument is required for %s\n", ++ vars[c]); ++ retval = -1; ++ } else { ++ event_aa_denied_mask = strdup(optarg); ++ if (event_aa_denied_mask == NULL) ++ retval = -1; ++ c++; ++ } ++ break; ++ case S_AA_FSUID: ++ if (!optarg) { ++ fprintf(stderr, ++ "Argument is required for %s\n", ++ vars[c]); ++ retval = -1; ++ break; ++ } ++ if (isdigit(optarg[0])) { ++ errno = 0; ++ event_aa_fsuid = strtol(optarg, NULL, 10); ++ if (errno) ++ retval = -1; ++ c++; ++ } else { ++ fprintf(stderr, ++ "fsuid must be a numeric value, was %s\n", ++ optarg); ++ retval = -1; ++ } ++ break; ++ case S_AA_OUID: ++ if (!optarg) { ++ fprintf(stderr, ++ "Argument is required for %s\n", ++ vars[c]); ++ retval = -1; ++ break; ++ } ++ if (isdigit(optarg[0])) { ++ errno = 0; ++ event_aa_ouid = strtol(optarg, NULL, 10); ++ if (errno) ++ retval = -1; ++ c++; ++ } else { ++ fprintf(stderr, ++ "ouid must be a numeric value, was %s\n", ++ optarg); ++ retval = -1; ++ } ++ break; ++ case S_AA_TARGET: ++ if (!optarg) { ++ fprintf(stderr, ++ "Argument is required for %s\n", ++ vars[c]); ++ retval = -1; ++ } else { ++ event_aa_target = strdup(optarg); ++ if (event_aa_target == NULL) ++ retval = -1; ++ c++; ++ } ++ break; ++ case S_AA_INFO: ++ if (!optarg) { ++ fprintf(stderr, ++ "Argument is required for %s\n", ++ vars[c]); ++ retval = -1; ++ } else { ++ event_aa_info = strdup(optarg); ++ if (event_aa_info == NULL) ++ retval = -1; ++ c++; ++ } ++ break; ++ case S_AA_CAPNAME: ++ if (!optarg) { ++ fprintf(stderr, ++ "Argument is required for %s\n", ++ vars[c]); ++ retval = -1; ++ } else { ++ event_aa_capname = strdup(optarg); ++ if (event_aa_capname == NULL) ++ retval = -1; ++ c++; ++ } ++ break; ++ case S_AA_ERROR: ++ if (!optarg) { ++ fprintf(stderr, ++ "Argument is required for %s\n", ++ vars[c]); ++ retval = -1; ++ break; ++ } ++ if (isdigit(optarg[0])) { ++ errno = 0; ++ event_aa_error = strtol(optarg, NULL, 10); ++ if (errno) ++ retval = -1; ++ c++; ++ } else { ++ fprintf(stderr, ++ "error must be a numeric value, was %s\n", ++ optarg); ++ retval = -1; ++ } ++ break; ++ case S_AA_NAMESPACE: ++ if (!optarg) { ++ fprintf(stderr, ++ "Argument is required for %s\n", ++ vars[c]); ++ retval = -1; ++ } else { ++ event_aa_namespace = strdup(optarg); ++ if (event_aa_namespace == NULL) ++ retval = -1; ++ c++; ++ } ++ break; ++ case S_AA_RLIMIT: ++ if (!optarg) { ++ fprintf(stderr, ++ "Argument is required for %s\n", ++ vars[c]); ++ retval = -1; ++ } else { ++ event_aa_rlimit = strdup(optarg); ++ if (event_aa_rlimit == NULL) ++ retval = -1; ++ c++; ++ } ++ break; ++ case S_AA_LADDR: ++ if (!optarg) { ++ fprintf(stderr, ++ "Argument is required for %s\n", ++ vars[c]); ++ retval = -1; ++ } else { ++ event_aa_laddr = strdup(optarg); ++ if (event_aa_laddr == NULL) ++ retval = -1; ++ c++; ++ } ++ break; ++ case S_AA_FADDR: ++ if (!optarg) { ++ fprintf(stderr, ++ "Argument is required for %s\n", ++ vars[c]); ++ retval = -1; ++ } else { ++ event_aa_faddr = strdup(optarg); ++ if (event_aa_faddr == NULL) ++ retval = -1; ++ c++; ++ } ++ break; ++ case S_AA_LPORT: ++ if (!optarg) { ++ fprintf(stderr, ++ "Argument is required for %s\n", ++ vars[c]); ++ retval = -1; ++ break; ++ } ++ if (isdigit(optarg[0])) { ++ errno = 0; ++ event_aa_lport = strtol(optarg, NULL, 10); ++ if (errno) ++ retval = -1; ++ c++; ++ } else { ++ fprintf(stderr, ++ "lport must be a numeric value, was %s\n", ++ optarg); ++ retval = -1; ++ } ++ break; ++ case S_AA_FPORT: ++ if (!optarg) { ++ fprintf(stderr, ++ "Argument is required for %s\n", ++ vars[c]); ++ retval = -1; ++ break; ++ } ++ if (isdigit(optarg[0])) { ++ errno = 0; ++ event_aa_fport = strtol(optarg, NULL, 10); ++ if (errno) ++ retval = -1; ++ c++; ++ } else { ++ fprintf(stderr, ++ "fport must be a numeric value, was %s\n", ++ optarg); ++ retval = -1; ++ } ++ break; ++ case S_AA_FAMILY: ++ if (!optarg) { ++ fprintf(stderr, ++ "Argument is required for %s\n", ++ vars[c]); ++ retval = -1; ++ } else { ++ event_aa_family = strdup(optarg); ++ if (event_aa_family == NULL) ++ retval = -1; ++ c++; ++ } ++ break; ++ case S_AA_SOCK_TYPE: ++ if (!optarg) { ++ fprintf(stderr, ++ "Argument is required for %s\n", ++ vars[c]); ++ retval = -1; ++ } else { ++ event_aa_sock_type = strdup(optarg); ++ if (event_aa_sock_type == NULL) ++ retval = -1; ++ c++; ++ } ++ break; ++ case S_AA_PROTOCOL: ++ if (!optarg) { ++ fprintf(stderr, ++ "Argument is required for %s\n", ++ vars[c]); ++ retval = -1; ++ break; ++ } ++ if (isdigit(optarg[0])) { ++ errno = 0; ++ event_aa_protocol = strtol(optarg, NULL, 10); ++ if (errno) ++ retval = -1; ++ c++; ++ } else { ++ fprintf(stderr, ++ "protocol must be a numeric value, was %s\n", ++ optarg); ++ retval = -1; ++ } ++ break; + default: + fprintf(stderr, "%s is an unsupported option\n", + vars[c]); +diff --git a/src/ausearch-parse.c b/src/ausearch-parse.c +index 08fa2be..55175b6 100644 +--- a/src/ausearch-parse.c ++++ b/src/ausearch-parse.c +@@ -1366,6 +1366,461 @@ static int parse_integrity(const lnode *n, search_items *s) + return 0; + } + ++/* ++ * Parse AppArmor specific fields. ++ * Note that this must be done before parsing all SELinux and common fields ++ * in parse_avc(), because parse_avc() relies on specific ordering of the ++ * fields and once it parses one, it doesn't look behind for other fields. ++ * This makes it complex to parse AppArmor fields, since many appear in ++ * the middle of common fields. So to make this AppArmor support simpler ++ * to maintain, move the parsing to a dedicate function that doesn't move ++ * the current "cursor" in the log line and doesn't depend on specific ++ * orderings. ++ */ ++static int parse_avc_apparmor_fields(char *term, search_items *s) ++{ ++ char *str; ++ char *tmp = term; ++ ++ if (event_aa_apparmor) { ++ str = strstr(term, "apparmor="); ++ if (str) { ++ str += 9; ++ if (*str != '"') ++ return 100; ++ str++; ++ term = strchr(str, '"'); ++ if (term == NULL) ++ return 100; ++ *term = 0; ++ s->aa_apparmor = strdup(str); ++ *term = '"'; ++ if (s->aa_apparmor == NULL) ++ return 100; ++ term = tmp; ++ } ++ } ++ ++ if (event_aa_operation) { ++ str = strstr(term, "operation="); ++ if (str) { ++ str += 10; ++ if (*str != '"') ++ return 101; ++ str++; ++ term = strchr(str, '"'); ++ if (term == NULL) ++ return 101; ++ *term = 0; ++ s->aa_operation = strdup(str); ++ *term = '"'; ++ if (s->aa_operation == NULL) ++ return 101; ++ term = tmp; ++ } ++ } ++ ++ if (event_aa_profile) { ++ str = strstr(term, "profile="); ++ if (str) { ++ str += 8; ++ if (*str != '"') ++ return 102; ++ str++; ++ term = strchr(str, '"'); ++ if (term == NULL) ++ return 102; ++ *term = 0; ++ s->aa_profile = strdup(str); ++ *term = '"'; ++ if (s->aa_profile == NULL) ++ return 102; ++ term = tmp; ++ } ++ } ++ ++ if (event_aa_parent != -1) { ++ str = strstr(term, "parent="); ++ if (str) { ++ str += 7; ++ term = strchr(str, ' '); ++ errno = 0; ++ if (term) { ++ /* We aren't the last field in the line. */ ++ *term = 0; ++ s->aa_parent = strtoul(str, NULL, 10); ++ *term = ' '; ++ } else { ++ /* We are the last field in the line. */ ++ s->aa_parent = strtoul(str, NULL, 10); ++ } ++ if (errno) ++ return 103; ++ term = tmp; ++ } ++ } ++ ++ if (event_aa_requested_mask) { ++ str = strstr(term, "requested_mask="); ++ if (str) { ++ str += 15; ++ if (*str != '"') ++ return 104; ++ str++; ++ term = strchr(str, '"'); ++ if (term == NULL) ++ return 104; ++ *term = 0; ++ s->aa_requested_mask = strdup(str); ++ *term = '"'; ++ if (s->aa_requested_mask == NULL) ++ return 104; ++ term = tmp; ++ } ++ } ++ ++ if (event_aa_denied_mask) { ++ str = strstr(term, "denied_mask="); ++ if (str) { ++ str += 12; ++ if (*str != '"') ++ return 105; ++ str++; ++ term = strchr(str, '"'); ++ if (term == NULL) ++ return 105; ++ *term = 0; ++ s->aa_denied_mask = strdup(str); ++ *term = '"'; ++ if (s->aa_denied_mask == NULL) ++ return 105; ++ term = tmp; ++ } ++ } ++ ++ if (event_aa_fsuid != -1) { ++ str = strstr(term, "fsuid="); ++ if (str) { ++ str += 6; ++ term = strchr(str, ' '); ++ errno = 0; ++ if (term) { ++ /* We aren't the last field in the line. */ ++ *term = 0; ++ s->aa_fsuid = strtoul(str, NULL, 10); ++ *term = ' '; ++ } else { ++ /* We are the last field in the line. */ ++ s->aa_fsuid = strtoul(str, NULL, 10); ++ } ++ if (errno) ++ return 106; ++ term = tmp; ++ } ++ } ++ ++ if (event_aa_ouid != -1) { ++ str = strstr(term, "ouid="); ++ if (str) { ++ str += 5; ++ term = strchr(str, ' '); ++ errno = 0; ++ if (term) { ++ /* We aren't the last field in the line. */ ++ *term = 0; ++ s->aa_ouid = strtoul(str, NULL, 10); ++ *term = ' '; ++ } else { ++ /* We are the last field in the line. */ ++ s->aa_ouid = strtoul(str, NULL, 10); ++ } ++ if (errno) ++ return 107; ++ term = tmp; ++ } ++ } ++ ++ if (event_aa_target) { ++ str = strstr(term, "target="); ++ if (str) { ++ str += 7; ++ if (*str != '"') ++ return 108; ++ str++; ++ term = strchr(str, '"'); ++ if (term == NULL) ++ return 108; ++ *term = 0; ++ s->aa_target = strdup(str); ++ *term = '"'; ++ if (s->aa_target == NULL) ++ return 108; ++ term = tmp; ++ } ++ } ++ ++ if (event_aa_info) { ++ str = strstr(term, "info="); ++ if (str) { ++ str += 5; ++ if (*str != '"') ++ return 109; ++ str++; ++ term = strchr(str, '"'); ++ if (term == NULL) ++ return 109; ++ *term = 0; ++ s->aa_info = strdup(str); ++ *term = '"'; ++ if (s->aa_info == NULL) ++ return 109; ++ term = tmp; ++ } ++ } ++ ++ if (event_aa_capname) { ++ str = strstr(term, "capname="); ++ if (str) { ++ str += 8; ++ if (*str != '"') ++ return 110; ++ str++; ++ term = strchr(str, '"'); ++ if (term == NULL) ++ return 110; ++ *term = 0; ++ s->aa_capname = strdup(str); ++ *term = '"'; ++ if (s->aa_capname == NULL) ++ return 110; ++ term = tmp; ++ } ++ } ++ ++ if (event_aa_error != -1) { ++ str = strstr(term, "error="); ++ if (str) { ++ str += 6; ++ term = strchr(str, ' '); ++ errno = 0; ++ if (term) { ++ /* We aren't the last field in the line. */ ++ *term = 0; ++ s->aa_error = strtoul(str, NULL, 10); ++ *term = ' '; ++ } else { ++ /* We are the last field in the line. */ ++ s->aa_error = strtoul(str, NULL, 10); ++ } ++ if (errno) ++ return 111; ++ term = tmp; ++ } ++ } ++ ++ if (event_aa_namespace) { ++ str = strstr(term, "namespace="); ++ if (str) { ++ str += 10; ++ if (*str != '"') ++ return 112; ++ str++; ++ term = strchr(str, '"'); ++ if (term == NULL) ++ return 112; ++ *term = 0; ++ s->aa_namespace = strdup(str); ++ *term = '"'; ++ if (s->aa_namespace == NULL) ++ return 112; ++ term = tmp; ++ } ++ } ++ ++ if (event_aa_rlimit) { ++ str = strstr(term, "rlimit="); ++ if (str) { ++ str += 7; ++ term = strchr(str, ' '); ++ if (term) { ++ /* We aren't the last field in the line. */ ++ *term = 0; ++ s->aa_rlimit = strdup(str); ++ *term = ' '; ++ } else { ++ /* We are the last field in the line. */ ++ s->aa_rlimit = strdup(str); ++ } ++ if (s->aa_rlimit == NULL) ++ return 113; ++ term = tmp; ++ } ++ } ++ ++ if (event_aa_laddr) { ++ str = strstr(term, "laddr="); ++ if (str) { ++ str += 6; ++ if (*str == '"') { ++ str++; ++ term = strchr(str, '"'); ++ if (term == NULL) ++ return 114; ++ *term = 0; ++ s->aa_laddr = strdup(str); ++ *term = '"'; ++ } else { ++ term = strchr(str, ' '); ++ if (term) { ++ /* We aren't the last field in the line. */ ++ *term = 0; ++ s->aa_laddr = strdup(str); ++ *term = ' '; ++ } else { ++ /* We are the last field in the line. */ ++ s->aa_laddr = strdup(str); ++ } ++ } ++ if (s->aa_laddr == NULL) ++ return 114; ++ term = tmp; ++ } ++ } ++ ++ if (event_aa_faddr) { ++ str = strstr(term, "faddr="); ++ if (str) { ++ str += 6; ++ if (*str == '"') { ++ str++; ++ term = strchr(str, '"'); ++ if (term == NULL) ++ return 115; ++ *term = 0; ++ s->aa_faddr = strdup(str); ++ *term = '"'; ++ } else { ++ term = strchr(str, ' '); ++ if (term) { ++ /* We aren't the last field in the line. */ ++ *term = 0; ++ s->aa_faddr = strdup(str); ++ *term = ' '; ++ } else { ++ /* We are the last field in the line. */ ++ s->aa_faddr = strdup(str); ++ } ++ } ++ if (s->aa_faddr == NULL) ++ return 115; ++ term = tmp; ++ } ++ } ++ ++ if (event_aa_lport != -1) { ++ str = strstr(term, "lport="); ++ if (str) { ++ str += 6; ++ term = strchr(str, ' '); ++ errno = 0; ++ if (term) { ++ /* We aren't the last field in the line. */ ++ *term = 0; ++ s->aa_lport = strtoul(str, NULL, 10); ++ *term = ' '; ++ } else { ++ /* We are the last field in the line. */ ++ s->aa_lport = strtoul(str, NULL, 10); ++ } ++ if (errno) ++ return 116; ++ term = tmp; ++ } ++ } ++ ++ if (event_aa_fport != -1) { ++ str = strstr(term, "fport="); ++ if (str) { ++ str += 6; ++ term = strchr(str, ' '); ++ errno = 0; ++ if (term) { ++ /* We aren't the last field in the line. */ ++ *term = 0; ++ s->aa_fport = strtoul(str, NULL, 10); ++ *term = ' '; ++ } else { ++ /* We are the last field in the line. */ ++ s->aa_fport = strtoul(str, NULL, 10); ++ } ++ if (errno) ++ return 117; ++ term = tmp; ++ } ++ } ++ ++ if (event_aa_family) { ++ str = strstr(term, "family="); ++ if (str) { ++ str += 7; ++ if (*str != '"') ++ return 118; ++ str++; ++ term = strchr(str, '"'); ++ if (term == NULL) ++ return 118; ++ *term = 0; ++ s->aa_family = strdup(str); ++ *term = '"'; ++ if (s->aa_family == NULL) ++ return 118; ++ term = tmp; ++ } ++ } ++ ++ if (event_aa_sock_type) { ++ str = strstr(term, "sock_type="); ++ if (str) { ++ str += 10; ++ if (*str != '"') ++ return 119; ++ str++; ++ term = strchr(str, '"'); ++ if (term == NULL) ++ return 119; ++ *term = 0; ++ s->aa_sock_type = strdup(str); ++ *term = '"'; ++ if (s->aa_sock_type == NULL) ++ return 119; ++ term = tmp; ++ } ++ } ++ ++ if (event_aa_protocol != -1) { ++ str = strstr(term, "protocol="); ++ if (str) { ++ str += 9; ++ term = strchr(str, ' '); ++ errno = 0; ++ if (term) { ++ /* We aren't the last field in the line. */ ++ *term = 0; ++ s->aa_protocol = strtoul(str, NULL, 10); ++ *term = ' '; ++ } else { ++ /* We are the last field in the line. */ ++ s->aa_protocol = strtoul(str, NULL, 10); ++ } ++ if (errno) ++ return 120; ++ term = tmp; ++ } ++ } ++ ++ return 0; ++} ++ + + /* FIXME: If they are in permissive mode or hit an auditallow, there can + * be more that 1 avc in the same syscall. For now, we pickup just the first. +@@ -1379,6 +1834,10 @@ static int parse_avc(const lnode *n, search_items *s) + term = n->message; + anode_init(&an); + ++ rc = parse_avc_apparmor_fields(term, s); ++ if (rc) ++ goto err; ++ + // get the avc message info. + str = strstr(term, "avc: "); + if (str) { +-- +1.8.4.5 + diff --git a/audit-secondary.spec b/audit-secondary.spec index e9f81a9..8c8865c 100644 --- a/audit-secondary.spec +++ b/audit-secondary.spec @@ -1,7 +1,7 @@ # # spec file for package audit-secondary # -# Copyright (c) 2014 SUSE LINUX Products GmbH, Nuernberg, Germany. +# Copyright (c) 2015 SUSE LINUX Products GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -39,6 +39,7 @@ Patch2: audit-no-gss.patch Patch3: audit-no_m4_dir.patch Patch4: audit-allow-manual-stop.patch Patch5: audit-ausearch-do-not-require-tclass.patch +Patch6: audit-ausearch-filter-apparmor-events.patch BuildRoot: %{_tmppath}/%{name}-%{version}-build BuildRequires: audit-devel = %{version} BuildRequires: autoconf >= 2.12 @@ -96,6 +97,7 @@ rm -rf audisp/plugins/prelude %patch3 -p1 %patch4 -p1 %patch5 -p1 +%patch6 -p1 %build autoreconf -fi export CFLAGS="%{optflags} -fno-strict-aliasing" diff --git a/audit.changes b/audit.changes index 00380d9..5426ede 100644 --- a/audit.changes +++ b/audit.changes @@ -1,3 +1,9 @@ +------------------------------------------------------------------- +Thu Jan 29 12:17:30 UTC 2015 - fdmanana@suse.com + +- Teach ausearch to filter AppArmor events (Fate#317726). + Added patch file audit-ausearch-filter-apparmor-events.patch + ------------------------------------------------------------------- Mon Nov 24 14:55:22 UTC 2014 - mq@suse.cz diff --git a/audit.spec b/audit.spec index 269c3c0..aee5b1f 100644 --- a/audit.spec +++ b/audit.spec @@ -1,7 +1,7 @@ # # spec file for package audit # -# Copyright (c) 2014 SUSE LINUX Products GmbH, Nuernberg, Germany. +# Copyright (c) 2015 SUSE LINUX Products GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed From 35ac1a5f7347f7ebebe7a71c6b1538bf983b73928aa45ef81c1bb802cee18c3d Mon Sep 17 00:00:00 2001 From: Tony Jones Date: Thu, 29 Jan 2015 20:31:09 +0000 Subject: [PATCH 2/4] Accepting request 283377 from security revert to r75 OBS-URL: https://build.opensuse.org/request/show/283377 OBS-URL: https://build.opensuse.org/package/show/security/audit?expand=0&rev=77 --- audit-ausearch-filter-apparmor-events.patch | 1490 ------------------- audit-secondary.spec | 4 +- audit.changes | 6 - audit.spec | 2 +- 4 files changed, 2 insertions(+), 1500 deletions(-) delete mode 100644 audit-ausearch-filter-apparmor-events.patch diff --git a/audit-ausearch-filter-apparmor-events.patch b/audit-ausearch-filter-apparmor-events.patch deleted file mode 100644 index 1fc12af..0000000 --- a/audit-ausearch-filter-apparmor-events.patch +++ /dev/null @@ -1,1490 +0,0 @@ -From: Filipe Manana -Date: Wed, 28 Jan 2015 16:08:01 +0000 -References: Fate#317726 -Upstream: never -Subject: [PATCH] Teach ausearch to filter AppArmor events - -This changes makes ausearch able to filter AppArmor events according -to its specific fields. Several new command line parameters allow to -filter events by specific values, whose key matches the command line -parameters' names. These new parameters are: - - --apparmor - --operation - --profile - --parent - --requested_mask - --denied_mask - --fsuid - --ouid - --target - --info - --capname - --error - --namespace - --rlimit - --laddr - --faddr - --lport - --fport - --family - --sock_type - --protocol - -Usage examples: - - $ ausearch -if log.txt --apparmor DENIED - ---- - time->Mon Jan 19 20:08:24 2015 - type=1400 audit(1421698104.388:45): apparmor="DENIED" operation="open" parent=2442 profile="/usr/bin/xchat" name="/dev/shm/pulse-shm-1760669882" pid=2934 comm="xchat" - requested_mask="r" denied_mask="r" fsuid=1000 ouid=1000 - ---- - time->Mon Jan 19 20:08:24 2015 - type=1400 audit(1421698104.388:47): apparmor="DENIED" operation="mknod" parent=2442 profile="/usr/bin/xchat" name="/dev/shm/pulse-shm-1001794793" pid=2934 comm="xchat" - requested_mask="c" denied_mask="c" fsuid=1000 ouid=1000 - - $ ausearch -if log.txt --apparmor DENIED --operation mknod - ---- - time->Mon Jan 19 20:08:24 2015 - type=1400 audit(1421698104.388:47): apparmor="DENIED" operation="mknod" parent=2442 profile="/usr/bin/xchat" name="/dev/shm/pulse-shm-1001794793" pid=2934 comm="xchat" - requested_mask="c" denied_mask="c" fsuid=1000 ouid=1000 - - $ ausearch -if log.txt --comm xchat --fport 6697 - ---- - time->Sun Jan 18 18:37:45 2015 - type=1400 audit(1421606265.719:2082): apparmor="ALLOWED" operation="recvmsg" parent=2391 profile="/usr/bin/xchat" pid=4107 comm="xchat" laddr=10.163.0.243 lport=55184 - faddr=149.44.176.29 fport=6697 family="inet" sock_type="stream" protocol=6 - ---- - time->Sun Jan 18 18:37:46 2015 - type=1400 audit(1421606266.203:2098): apparmor="ALLOWED" operation="sendmsg" parent=2391 profile="/usr/bin/xchat" pid=4107 comm="xchat" laddr=10.163.0.243 lport=55184 - faddr=149.44.176.29 fport=6697 family="inet" sock_type="stream" protocol=6 - ---- - time->Sun Jan 18 18:37:46 2015 - type=1400 audit(1421606266.259:2101): apparmor="ALLOWED" operation="recvmsg" parent=2391 profile="/usr/bin/xchat" pid=4107 comm="xchat" laddr=10.163.0.243 lport=55184 - faddr=149.44.176.29 fport=6697 family="inet" sock_type="stream" protocol=6 - ---- - time->Sun Jan 18 18:37:48 2015 - type=1400 audit(1421606268.207:2104): apparmor="ALLOWED" operation="sendmsg" parent=2391 profile="/usr/bin/xchat" pid=4107 comm="xchat" laddr=10.163.0.243 lport=55184 - faddr=149.44.176.29 fport=6697 family="inet" sock_type="stream" protocol=6 - - $ ausearch -if log.txt --comm xchat --fport 6697 --operation sendmsg - - time->Sun Jan 18 18:37:46 2015 - type=1400 audit(1421606266.203:2098): apparmor="ALLOWED" operation="sendmsg" parent=2391 profile="/usr/bin/xchat" pid=4107 comm="xchat" laddr=10.163.0.243 lport=55184 - faddr=149.44.176.29 fport=6697 family="inet" sock_type="stream" protocol=6 - ---- - time->Sun Jan 18 18:37:48 2015 - type=1400 audit(1421606268.207:2104): apparmor="ALLOWED" operation="sendmsg" parent=2391 profile="/usr/bin/xchat" pid=4107 comm="xchat" laddr=10.163.0.243 lport=55184 - faddr=149.44.176.29 fport=6697 family="inet" sock_type="stream" protocol=6 - -Signed-off-by: Filipe Manana ---- - docs/ausearch.8 | 63 +++++++ - src/aureport-options.c | 23 +++ - src/ausearch-common.h | 23 +++ - src/ausearch-llist.c | 56 ++++++ - src/ausearch-llist.h | 22 +++ - src/ausearch-lol.c | 2 +- - src/ausearch-match.c | 119 +++++++++++++ - src/ausearch-options.c | 404 ++++++++++++++++++++++++++++++++++++++++++- - src/ausearch-parse.c | 459 +++++++++++++++++++++++++++++++++++++++++++++++++ - 9 files changed, 1168 insertions(+), 3 deletions(-) - -diff --git a/docs/ausearch.8 b/docs/ausearch.8 -index 54018ae..c441f7c 100644 ---- a/docs/ausearch.8 -+++ b/docs/ausearch.8 -@@ -18,15 +18,39 @@ Also be aware that not all record types have the requested information. For exam - .BR \-a ,\ \-\-event \ \fIaudit-event-id\fP - Search for an event based on the given \fIevent ID\fP. Messages always start with something like msg=audit(1116360555.329:2401771). The event ID is the number after the ':'. All audit events that are recorded from one application's syscall have the same audit event ID. A second syscall made by the same application will have a different event ID. This way they are unique. - .TP -+.BR \-\-apparmor \ \fItype\fP -+Search for an event matching the given AppArmor \fItype\fP value. This filters events from AppArmor wich have an attribute like apparmor="ALLOWED" for example. -+.TP -+.BR \-\-capname \ \fIcapname\fP -+Search for an event based on the given capability name \fIcapname\fP (AppArmor events). -+.TP - .BR \-c ,\ \-\-comm \ \fIcomm-name\fP - Search for an event based on the given \fIcomm name\fP. The comm name is the executable's name from the task structure. - .TP -+.BR \-\-denied_mask \ \fImask\fP -+Search for an event matching the given denied \fImask\fP (AppArmor events). -+.TP -+.BR \-\-error \ \fIerror\fP -+Search for an event based on the given \fIerror\fP (AppArmor events). -+.TP - .BR \-e,\ \-\-exit \ \fIexit-code-or-errno\fP - Search for an event based on the given syscall \fIexit code or errno\fP. - .TP -+.BR \-\-faddr \ \fIaddress\fP -+Search for an event based on the given foreign \fIaddress\fP (AppArmor events). -+.TP -+.BR \-\-family \ \fIfamily\fP -+Search for an event based on the given network \fIfamily\fP (AppArmor events). -+.TP - .BR \-f ,\ \-\-file \ \fIfile-name\fP - Search for an event based on the given \fIfilename\fP. - .TP -+.BR \-\-fport \ \fIport\fP -+Search for an event based on the given foreign \fport\fP (AppArmor events). -+.TP -+.BR \-\-fsuid \ \fIfsuid\fP -+Search for an event based on the given \fIfsuid\fP (AppArmor events). -+.TP - .BR \-ga ,\ \-\-gid-all \ \fIall-group-id\fP - Search for an event with either effective group ID or group ID matching the given \fIgroup ID\fP. - .TP -@@ -45,6 +69,9 @@ Search for an event with the given \fIhost name\fP. The hostname can be either a - .BR \-i ,\ \-\-interpret - Interpret numeric entities into text. For example, uid is converted to account name. The conversion is done using the current resources of the machine where the search is being run. If you have renamed the accounts, or don't have the same accounts on your machine, you could get misleading results. - .TP -+.BR \-\-info \ \fIinfo\fP -+Search for an event matching the given \fIinfo\fP value (AppArmor events). -+.TP - .BR \-if ,\ \-\-input \ \fIfile-name\fP - Use the given \fIfile\fP instead of the logs. This is to aid analysis where the logs have been moved to another machine or only part of a log was saved. - .TP -@@ -57,27 +84,57 @@ Stop after emitting the first event that matches the search criteria. - .BR \-k ,\ \-\-key \ \fIkey-string\fP - Search for an event based on the given \fIkey string\fP. - .TP -+.BR \-\-laddr \ \fIaddress\fP -+Search for an event based on the given local \fIaddress\fP (AppArmor events). -+.TP - .BR \-l ,\ \-\-line-buffered - Flush output on every line. Most useful when stdout is connected to a pipe and the default block buffering strategy is undesirable. May impose a performance penalty. - .TP -+.BR \-\-lport \ \fIport\fP -+Search for an event based on the given local \fport\fP (AppArmor events). -+.TP - .BR \-m ,\ \-\-message \ \fImessage-type\fP\ |\ \fIcomma-sep-message-type-list\fP - Search for an event matching the given \fImessage type\fP. You may also enter a \fIcomma separated list of message types\fP. There is an \fBALL\fP message type that doesn't exist in the actual logs. It allows you to get all messages in the system. The list of valid messages types is long. The program will display the list whenever no message type is passed with this parameter. The message type can be either text or numeric. If you enter a list, there can be only commas and no spaces separating the list. - .TP -+.BR \-\-namespace \ \fInamespace\fP -+Search for an event matching the given \fInamespace\fP (AppArmor events). -+.TP - .BR \-n ,\ \-\-node \ \fInode-name\fP - Search for events originating from \fInode name\fP string. Multiple nodes are allowed, and if any nodes match, the event is matched. - .TP - .BR \-o ,\ \-\-object \ \fISE-Linux-context-string\fP - Search for event with \fItcontext\fP (object) matching the string. - .TP -+.BR \-\-operation \ \fIoperation\fP -+Search for an event matching the given \fIoperation\fP (AppArmor events). -+.TP -+.BR \-\-ouid \ \fIouid\fP -+Search for an event based on the given \fIouid\fP (AppArmor events). -+.TP - .BR \-p ,\ \-\-pid \ \fIprocess-id\fP - Search for an event matching the given \fIprocess ID\fP. - .TP - .BR \-pp ,\ \-\-ppid \ \fIparent-process-id\fP - Search for an event matching the given \fIparent process ID\fP. - .TP -+.BR \-\-parent \ \fIparent\fP -+Search for an event matching the given \fIparent\fP (AppArmor events). -+.TP -+.BR \-\-profile \ \fIprofile\fP -+Search for an event matching the given \fIprofile\fP (AppArmor events). -+.TP -+.BR \-\-protocol \ \fIprotocol\fP -+Search for an event matching the given \fIprotocol\fP (AppArmor events). -+.TP - .BR \-r ,\ \-\-raw - Output is completely unformatted. This is useful for extracting records that can still be interpreted by audit tools. - .TP -+.BR \-\-requested_mask \ \fImask\fP -+Search for an event matching the given requested \fImask\fP (AppArmor events). -+.TP -+.BR \-\-rlimit \ \fIrlimit\fP -+Search for an event matching the given \fIrlimit\fP (AppArmor events). -+.TP - .BR \-sc ,\ \-\-syscall \ \fIsyscall-name-or-value\fP - Search for an event matching the given \fIsyscall\fP. You may either give the numeric syscall value or the syscall name. If you give the syscall name, it will use the syscall table for the machine that you are using. - .TP -@@ -87,6 +144,9 @@ Search for event with either \fIscontext\fP/subject or \fItcontext\fP/object mat - .BR \-\-session \ \fILogin-Session-ID\fP - Search for events matching the given Login Session ID. This process attribute is set when a user logs in and can tie any process to a particular user login. - .TP -+.BR \-\-sock_type \ \fIsocket-type\fP -+Search for an event based on the given \fIsocket-type\fP (AppArmor events). -+.TP - .BR \-su ,\ \-\-subject \ \fISE-Linux-context-string\fP - Search for event with \fIscontext\fP (subject) matching the string. - .TP -@@ -96,6 +156,9 @@ Search for an event matching the given \fIsuccess value\fP. Legal values are - and - .BR no . - .TP -+.BR \-\-target \ \fItarget\fP -+Search for events matching the given \fItarget\fP (AppArmor events). -+.TP - .BR \-te ,\ \-\-end \ [\fIend-date\fP]\ [\fIend-time\fP] - Search for events with time stamps equal to or before the given end time. The format of end time depends on your locale. If the date is omitted, - .B today -diff --git a/src/aureport-options.c b/src/aureport-options.c -index f1ab50a..f5a9ac1 100644 ---- a/src/aureport-options.c -+++ b/src/aureport-options.c -@@ -51,6 +51,29 @@ const char *event_subject = NULL; - const char *event_object = NULL; - int event_exit = 0, event_exit_is_set = 0; - int event_ppid = -1, event_session_id = -2; -+/* AppArmor specific search fields */ -+const char *event_aa_apparmor = NULL; -+const char *event_aa_operation = NULL; -+const char *event_aa_profile = NULL; -+pid_t event_aa_parent = -1; -+const char *event_aa_requested_mask = NULL; -+const char *event_aa_denied_mask = NULL; -+uid_t event_aa_fsuid = -1; -+uid_t event_aa_ouid = -1; -+const char *event_aa_target = NULL; -+const char *event_aa_info = NULL; -+const char *event_aa_capname = NULL; -+long event_aa_error = 0; -+const char *event_aa_namespace = NULL; -+const char *event_aa_rlimit = NULL; -+const char *event_aa_laddr = NULL; -+const char *event_aa_faddr = NULL; -+int event_aa_lport = -1; -+int event_aa_fport = -1; -+const char *event_aa_family = NULL; -+const char *event_aa_sock_type = NULL; -+int event_aa_protocol = -1; -+ - - /* These are used by aureport */ - const char *dummy = "dummy"; -diff --git a/src/ausearch-common.h b/src/ausearch-common.h -index 08b0cba..6509e0a 100644 ---- a/src/ausearch-common.h -+++ b/src/ausearch-common.h -@@ -42,6 +42,29 @@ extern int event_syscall; - extern const char *event_exe; - extern int event_ua, event_ga; - extern int event_exit, event_exit_is_set; -+/* AppArmor search fields. */ -+extern const char *event_aa_apparmor; -+extern const char *event_aa_operation; -+extern const char *event_aa_profile; -+extern pid_t event_aa_parent; -+extern const char *event_aa_requested_mask; -+extern const char *event_aa_denied_mask; -+extern uid_t event_aa_fsuid; -+extern uid_t event_aa_ouid; -+extern const char *event_aa_target; -+extern const char *event_aa_info; -+extern const char *event_aa_capname; -+extern long event_aa_error; -+extern const char *event_aa_namespace; -+extern const char *event_aa_rlimit; -+extern const char *event_aa_laddr; -+extern const char *event_aa_faddr; -+extern int event_aa_lport; -+extern int event_aa_fport; -+extern const char *event_aa_family; -+extern const char *event_aa_sock_type; -+extern int event_aa_protocol; -+ - - typedef enum { F_BOTH, F_FAILED, F_SUCCESS } failed_t; - typedef enum { C_NEITHER, C_ADD, C_DEL } conf_act_t; -diff --git a/src/ausearch-llist.c b/src/ausearch-llist.c -index 32cda7e..9077291 100644 ---- a/src/ausearch-llist.c -+++ b/src/ausearch-llist.c -@@ -57,6 +57,27 @@ void list_create(llist *l) - l->s.session_id = -2; - l->s.exit = 0; - l->s.exit_is_set = 0; -+ l->s.aa_apparmor = NULL; -+ l->s.aa_operation = NULL; -+ l->s.aa_profile = NULL; -+ l->s.aa_parent = -1; -+ l->s.aa_requested_mask = NULL; -+ l->s.aa_denied_mask = NULL; -+ l->s.aa_fsuid = -1; -+ l->s.aa_ouid = -1; -+ l->s.aa_target = NULL; -+ l->s.aa_info = NULL; -+ l->s.aa_capname = NULL; -+ l->s.aa_error = 0; -+ l->s.aa_namespace = NULL; -+ l->s.aa_rlimit = NULL; -+ l->s.aa_laddr = NULL; -+ l->s.aa_faddr = NULL; -+ l->s.aa_lport = -1; -+ l->s.aa_fport = -1; -+ l->s.aa_family = NULL; -+ l->s.aa_sock_type = NULL; -+ l->s.aa_protocol = -1; - } - - void list_last(llist *l) -@@ -199,6 +220,41 @@ void list_clear(llist* l) - l->s.session_id = -2; - l->s.exit = 0; - l->s.exit_is_set = 0; -+ free(l->s.aa_apparmor); -+ l->s.aa_apparmor = NULL; -+ free(l->s.aa_operation); -+ l->s.aa_operation = NULL; -+ free(l->s.aa_profile); -+ l->s.aa_profile = NULL; -+ l->s.aa_parent = -1; -+ free(l->s.aa_requested_mask); -+ l->s.aa_requested_mask = NULL; -+ free(l->s.aa_denied_mask); -+ l->s.aa_denied_mask = NULL; -+ l->s.aa_fsuid = -1; -+ l->s.aa_ouid = -1; -+ free(l->s.aa_target); -+ l->s.aa_target = NULL; -+ free(l->s.aa_info); -+ l->s.aa_info = NULL; -+ free(l->s.aa_capname); -+ l->s.aa_capname = NULL; -+ l->s.aa_error = 0; -+ free(l->s.aa_namespace); -+ l->s.aa_namespace = NULL; -+ free(l->s.aa_rlimit); -+ l->s.aa_rlimit = NULL; -+ free(l->s.aa_laddr); -+ l->s.aa_laddr = NULL; -+ free(l->s.aa_faddr); -+ l->s.aa_faddr = NULL; -+ l->s.aa_lport = -1; -+ l->s.aa_fport = -1; -+ free(l->s.aa_family); -+ l->s.aa_family = NULL; -+ free(l->s.aa_sock_type); -+ l->s.aa_sock_type = NULL; -+ l->s.aa_protocol = -1; - } - - int list_get_event(llist* l, event *e) -diff --git a/src/ausearch-llist.h b/src/ausearch-llist.h -index a77d800..09c7ac6 100644 ---- a/src/ausearch-llist.h -+++ b/src/ausearch-llist.h -@@ -64,6 +64,28 @@ typedef struct - char *comm; // comm name - alist *avc; // avcs for the event - char *acct; // account used when uid is invalid -+ // AppArmor specific fields -+ char *aa_apparmor; // ield apparmor=... -+ char *aa_operation; // field operation=... -+ char *aa_profile; // field profile=... -+ pid_t aa_parent; // field parent=... -+ char *aa_requested_mask; // field requested_mask=... -+ char *aa_denied_mask; // field denied_mask=... -+ uid_t aa_fsuid; // field fsuid=... -+ uid_t aa_ouid; // field ouid=... -+ char *aa_target; // field target=... -+ char *aa_info; // field info=... -+ char *aa_capname; // field capname=... -+ long aa_error; // field error=... -+ char *aa_namespace; // field namespace=... -+ char *aa_rlimit; // field rlimit=... -+ char *aa_laddr; // field laddr=... -+ char *aa_faddr; // field faddr=... -+ int aa_lport; // field lport=... -+ int aa_fport; // field fport=... -+ char *aa_family; // field family=... -+ char *aa_sock_type; // field sock_type=... -+ int aa_protocol; // field protocol=... - } search_items; - - /* This is the node of the linked list. Any data elements that are per -diff --git a/src/ausearch-lol.c b/src/ausearch-lol.c -index c291f5f..12b4a95 100644 ---- a/src/ausearch-lol.c -+++ b/src/ausearch-lol.c -@@ -28,7 +28,7 @@ - #include - #include "ausearch-common.h" - --#define ARRAY_LIMIT 80 -+#define ARRAY_LIMIT 8192 - static int ready = 0; - - void lol_create(lol *lo) -diff --git a/src/ausearch-match.c b/src/ausearch-match.c -index 24b9320..f78e705 100644 ---- a/src/ausearch-match.c -+++ b/src/ausearch-match.c -@@ -201,6 +201,125 @@ int match(llist *l) - return 0; - } - } -+ if (event_aa_apparmor) { -+ if (l->s.aa_apparmor == NULL) -+ return 0; -+ if (strmatch(event_aa_apparmor, -+ l->s.aa_apparmor) == 0) -+ return 0; -+ } -+ if (event_aa_operation) { -+ if (l->s.aa_operation == NULL) -+ return 0; -+ if (strmatch(event_aa_operation, -+ l->s.aa_operation) == 0) -+ return 0; -+ } -+ if (event_aa_profile) { -+ if (l->s.aa_profile == NULL) -+ return 0; -+ if (strmatch(event_aa_profile, -+ l->s.aa_profile) == 0) -+ return 0; -+ } -+ if ((event_aa_parent != -1) && -+ (event_aa_parent != l->s.aa_parent)) -+ return 0; -+ if (event_aa_requested_mask) { -+ if (l->s.aa_requested_mask == NULL) -+ return 0; -+ if (strmatch(event_aa_requested_mask, -+ l->s.aa_requested_mask) == 0) -+ return 0; -+ } -+ if (event_aa_denied_mask) { -+ if (l->s.aa_denied_mask == NULL) -+ return 0; -+ if (strmatch(event_aa_denied_mask, -+ l->s.aa_denied_mask) == 0) -+ return 0; -+ } -+ if ((event_aa_fsuid != -1) && -+ (event_aa_fsuid != l->s.aa_fsuid)) -+ return 0; -+ if ((event_aa_ouid != -1) && -+ (event_aa_ouid != l->s.aa_ouid)) -+ return 0; -+ if (event_aa_target) { -+ if (l->s.aa_target == NULL) -+ return 0; -+ if (strmatch(event_aa_target, -+ l->s.aa_target) == 0) -+ return 0; -+ } -+ if (event_aa_info) { -+ if (l->s.aa_info == NULL) -+ return 0; -+ if (strmatch(event_aa_info, -+ l->s.aa_info) == 0) -+ return 0; -+ } -+ if (event_aa_capname) { -+ if (l->s.aa_capname == NULL) -+ return 0; -+ if (strmatch(event_aa_capname, -+ l->s.aa_capname) == 0) -+ return 0; -+ } -+ if ((event_aa_error != 0) && -+ (event_aa_error != l->s.aa_error)) -+ return 0; -+ if (event_aa_namespace) { -+ if (l->s.aa_namespace == NULL) -+ return 0; -+ if (strmatch(event_aa_namespace, -+ l->s.aa_namespace) == 0) -+ return 0; -+ } -+ if (event_aa_rlimit) { -+ if (l->s.aa_rlimit == NULL) -+ return 0; -+ if (strmatch(event_aa_rlimit, -+ l->s.aa_rlimit) == 0) -+ return 0; -+ } -+ if (event_aa_laddr) { -+ if (l->s.aa_laddr == NULL) -+ return 0; -+ if (strmatch(event_aa_laddr, -+ l->s.aa_laddr) == 0) -+ return 0; -+ } -+ if (event_aa_faddr) { -+ if (l->s.aa_faddr == NULL) -+ return 0; -+ if (strmatch(event_aa_faddr, -+ l->s.aa_faddr) == 0) -+ return 0; -+ } -+ if ((event_aa_lport != -1) && -+ (event_aa_lport != l->s.aa_lport)) -+ return 0; -+ if ((event_aa_fport != -1) && -+ (event_aa_fport != l->s.aa_fport)) -+ return 0; -+ if (event_aa_family) { -+ if (l->s.aa_family == NULL) -+ return 0; -+ if (strmatch(event_aa_family, -+ l->s.aa_family) == 0) -+ return 0; -+ } -+ if (event_aa_sock_type) { -+ if (l->s.aa_sock_type == NULL) -+ return 0; -+ if (strmatch(event_aa_sock_type, -+ l->s.aa_sock_type) == 0) -+ return 0; -+ } -+ if ((event_aa_protocol != -1) && -+ (event_aa_protocol != l->s.aa_protocol)) -+ return 0; - if (context_match(l) == 0) - return 0; - return 1; -diff --git a/src/ausearch-options.c b/src/ausearch-options.c -index 8f4b64e..4e66771 100644 ---- a/src/ausearch-options.c -+++ b/src/ausearch-options.c -@@ -63,6 +63,28 @@ const char *event_subject = NULL; - const char *event_object = NULL; - report_t report_format = RPT_DEFAULT; - ilist *event_type; -+/* AppArmor specific search fields */ -+const char *event_aa_apparmor = NULL; -+const char *event_aa_operation = NULL; -+const char *event_aa_profile = NULL; -+pid_t event_aa_parent = -1; -+const char *event_aa_requested_mask = NULL; -+const char *event_aa_denied_mask = NULL; -+uid_t event_aa_fsuid = -1; -+uid_t event_aa_ouid = -1; -+const char *event_aa_target = NULL; -+const char *event_aa_info = NULL; -+const char *event_aa_capname = NULL; -+long event_aa_error = 0; -+const char *event_aa_namespace = NULL; -+const char *event_aa_rlimit = NULL; -+const char *event_aa_laddr = NULL; -+const char *event_aa_faddr = NULL; -+int event_aa_lport = -1; -+int event_aa_fport = -1; -+const char *event_aa_family = NULL; -+const char *event_aa_sock_type = NULL; -+int event_aa_protocol = -1; - - const slist *event_node_list = NULL; - -@@ -77,7 +99,13 @@ S_HOSTNAME, S_INTERP, S_INFILE, S_MESSAGE_TYPE, S_PID, S_SYSCALL, S_OSUCCESS, - S_TIME_END, S_TIME_START, S_TERMINAL, S_ALL_UID, S_EFF_UID, S_UID, S_LOGINID, - S_VERSION, S_EXACT_MATCH, S_EXECUTABLE, S_CONTEXT, S_SUBJECT, S_OBJECT, - S_PPID, S_KEY, S_RAW, S_NODE, S_IN_LOGS, S_JUST_ONE, S_SESSION, S_EXIT, --S_LINEBUFFERED }; -+S_LINEBUFFERED, -+/* AppArmor specific search options. */ -+S_AA_APPARMOR, S_AA_OPERATION, S_AA_PROFILE, S_AA_PARENT, -+S_AA_REQUESTED_MASK, S_AA_DENIED_MASK, S_AA_FSUID, S_AA_OUID, -+S_AA_TARGET, S_AA_INFO, S_AA_CAPNAME, S_AA_ERROR, S_AA_NAMESPACE, -+S_AA_RLIMIT, S_AA_LADDR, S_AA_FADDR, S_AA_LPORT, S_AA_FPORT, -+S_AA_FAMILY, S_AA_SOCK_TYPE, S_AA_PROTOCOL }; - - static struct nv_pair optiontab[] = { - { S_EVENT, "-a" }, -@@ -148,7 +176,29 @@ static struct nv_pair optiontab[] = { - { S_EXACT_MATCH, "-w" }, - { S_EXACT_MATCH, "--word" }, - { S_EXECUTABLE, "-x" }, -- { S_EXECUTABLE, "--executable" } -+ { S_EXECUTABLE, "--executable" }, -+ /* AppArmor specific search fields. */ -+ { S_AA_APPARMOR, "--apparmor" }, -+ { S_AA_OPERATION, "--operation" }, -+ { S_AA_PROFILE, "--profile" }, -+ { S_AA_PARENT, "--parent" }, -+ { S_AA_REQUESTED_MASK, "--requested_mask" }, -+ { S_AA_DENIED_MASK, "--denied_mask" }, -+ { S_AA_FSUID, "--fsuid" }, -+ { S_AA_OUID, "--ouid" }, -+ { S_AA_TARGET, "--target" }, -+ { S_AA_INFO, "--info" }, -+ { S_AA_CAPNAME, "--capname" }, -+ { S_AA_ERROR, "--error" }, -+ { S_AA_NAMESPACE, "--namespace" }, -+ { S_AA_RLIMIT, "--rlimit" }, -+ { S_AA_LADDR, "--laddr" }, -+ { S_AA_FADDR, "--faddr" }, -+ { S_AA_LPORT, "--lport" }, -+ { S_AA_FPORT, "--fport" }, -+ { S_AA_FAMILY, "--family" }, -+ { S_AA_SOCK_TYPE, "--sock_type" }, -+ { S_AA_PROTOCOL, "--protocol" }, - }; - #define OPTION_NAMES (sizeof(optiontab)/sizeof(optiontab[0])) - -@@ -167,9 +217,17 @@ static void usage(void) - { - printf("usage: ausearch [options]\n" - "\t-a,--event \tsearch based on audit event id\n" -+ "\t--apparmor \tsearch based on AppArmor type\n" -+ "\t--capname \tsearch based on capability name (AppArmor events)\n" - "\t-c,--comm \t\tsearch based on command line name\n" -+ "\t--denied_mask \t\tsearch based on denied mask (AppArmor events)\n" -+ "\t--error \tsearch based on error value (AppArmor events)\n" - "\t-e,--exit \tsearch based on syscall exit code\n" -+ "\t--faddr
\tsearch based on foreign address (AppArmor events)\n" -+ "\t--family \tsearch based on network family (AppArmor events)\n" - "\t-f,--file \t\tsearch based on file name\n" -+ "\t--fport \tsearch based on foreign port (AppArmor events)\n" -+ "\t--fsuid \t\tsearch based on fsuid (AppArmor events)\n" - "\t-ga,--gid-all \tsearch based on All group ids\n" - "\t-ge,--gid-effective search based on Effective\n\t\t\t\t\tgroup id\n" - "\t-gi,--gid \t\tsearch based on group id\n" -@@ -177,21 +235,34 @@ static void usage(void) - "\t-hn,--host \t\tsearch based on remote host name\n" - "\t-i,--interpret\t\t\tInterpret results to be human readable\n" - "\t-if,--input \tuse this file instead of current logs\n" -+ "\t--info \tsearch based on requested info (AppArmor events)\n" - "\t--input-logs\t\t\tUse the logs even if stdin is a pipe\n" - "\t--just-one\t\t\tEmit just one event\n" - "\t-k,--key \t\tsearch based on key field\n" -+ "\t--laddr
\tsearch based on local address (AppArmor events)\n" - "\t-l, --line-buffered\t\tFlush output on every line\n" -+ "\t--lport \tsearch based on local port (AppArmor events)\n" - "\t-m,--message \tsearch based on message type\n" -+ "\t--namespace \tsearch based on namespace (AppArmor events)\n" - "\t-n,--node \t\tsearch based on machine's name\n" - "\t-o,--object search based on context of object\n" -+ "\t--operation search based on operation (AppArmor events)\n" -+ "\t--ouid search based on ouid (AppArmor events)\n" - "\t-p,--pid \t\tsearch based on process id\n" - "\t-pp,--ppid \tsearch based on parent process id\n" -+ "\t--parent \tsearch based on parent (AppArmor events)\n" -+ "\t--profile \tsearch based on profile (AppArmor events)\n" -+ "\t--protocol \tsearch based on protocol (AppArmor events)\n" - "\t-r,--raw\t\t\toutput is completely unformatted\n" -+ "\t--requested_mask \tsearch based on requested mask (AppArmor events)\n" -+ "\t--rlimit \tsearch based on rlimit (AppArmor events)\n" - "\t-sc,--syscall \tsearch based on syscall name or number\n" - "\t-se,--context search based on either subject or\n\t\t\t\t\t object\n" - "\t--session \tsearch based on login session id\n" -+ "\t--sock_type search based on socket type (AppArmor events)\n" - "\t-su,--subject search based on context of the Subject\n" - "\t-sv,--success \tsearch based on syscall or event\n\t\t\t\t\tsuccess value\n" -+ "\t--target search based on target (AppArmor events)\n" - "\t-te,--end [end date] [end time]\tending date & time for search\n" - "\t-ts,--start [start date] [start time]\tstarting data & time for search\n" - "\t-tm,--terminal \tsearch based on terminal\n" -@@ -1026,6 +1097,335 @@ int check_params(int count, char *vars[]) - case S_LINEBUFFERED: - line_buffered = 1; - break; -+ case S_AA_APPARMOR: -+ if (!optarg) { -+ fprintf(stderr, -+ "Argument is required for %s\n", -+ vars[c]); -+ retval = -1; -+ } else { -+ event_aa_apparmor = strdup(optarg); -+ if (event_aa_apparmor == NULL) -+ retval = -1; -+ c++; -+ } -+ break; -+ case S_AA_OPERATION: -+ if (!optarg) { -+ fprintf(stderr, -+ "Argument is required for %s\n", -+ vars[c]); -+ retval = -1; -+ } else { -+ event_aa_operation = strdup(optarg); -+ if (event_aa_operation == NULL) -+ retval = -1; -+ c++; -+ } -+ break; -+ case S_AA_PROFILE: -+ if (!optarg) { -+ fprintf(stderr, -+ "Argument is required for %s\n", -+ vars[c]); -+ retval = -1; -+ } else { -+ event_aa_profile = strdup(optarg); -+ if (event_aa_profile == NULL) -+ retval = -1; -+ c++; -+ } -+ break; -+ case S_AA_PARENT: -+ if (!optarg) { -+ fprintf(stderr, -+ "Argument is required for %s\n", -+ vars[c]); -+ retval = -1; -+ break; -+ } -+ if (isdigit(optarg[0])) { -+ errno = 0; -+ event_aa_parent = strtol(optarg, NULL, 10); -+ if (errno) -+ retval = -1; -+ c++; -+ } else { -+ fprintf(stderr, -+ "Parent must be a numeric value, was %s\n", -+ optarg); -+ retval = -1; -+ } -+ break; -+ case S_AA_REQUESTED_MASK: -+ if (!optarg) { -+ fprintf(stderr, -+ "Argument is required for %s\n", -+ vars[c]); -+ retval = -1; -+ } else { -+ event_aa_requested_mask = strdup(optarg); -+ if (event_aa_requested_mask == NULL) -+ retval = -1; -+ c++; -+ } -+ break; -+ case S_AA_DENIED_MASK: -+ if (!optarg) { -+ fprintf(stderr, -+ "Argument is required for %s\n", -+ vars[c]); -+ retval = -1; -+ } else { -+ event_aa_denied_mask = strdup(optarg); -+ if (event_aa_denied_mask == NULL) -+ retval = -1; -+ c++; -+ } -+ break; -+ case S_AA_FSUID: -+ if (!optarg) { -+ fprintf(stderr, -+ "Argument is required for %s\n", -+ vars[c]); -+ retval = -1; -+ break; -+ } -+ if (isdigit(optarg[0])) { -+ errno = 0; -+ event_aa_fsuid = strtol(optarg, NULL, 10); -+ if (errno) -+ retval = -1; -+ c++; -+ } else { -+ fprintf(stderr, -+ "fsuid must be a numeric value, was %s\n", -+ optarg); -+ retval = -1; -+ } -+ break; -+ case S_AA_OUID: -+ if (!optarg) { -+ fprintf(stderr, -+ "Argument is required for %s\n", -+ vars[c]); -+ retval = -1; -+ break; -+ } -+ if (isdigit(optarg[0])) { -+ errno = 0; -+ event_aa_ouid = strtol(optarg, NULL, 10); -+ if (errno) -+ retval = -1; -+ c++; -+ } else { -+ fprintf(stderr, -+ "ouid must be a numeric value, was %s\n", -+ optarg); -+ retval = -1; -+ } -+ break; -+ case S_AA_TARGET: -+ if (!optarg) { -+ fprintf(stderr, -+ "Argument is required for %s\n", -+ vars[c]); -+ retval = -1; -+ } else { -+ event_aa_target = strdup(optarg); -+ if (event_aa_target == NULL) -+ retval = -1; -+ c++; -+ } -+ break; -+ case S_AA_INFO: -+ if (!optarg) { -+ fprintf(stderr, -+ "Argument is required for %s\n", -+ vars[c]); -+ retval = -1; -+ } else { -+ event_aa_info = strdup(optarg); -+ if (event_aa_info == NULL) -+ retval = -1; -+ c++; -+ } -+ break; -+ case S_AA_CAPNAME: -+ if (!optarg) { -+ fprintf(stderr, -+ "Argument is required for %s\n", -+ vars[c]); -+ retval = -1; -+ } else { -+ event_aa_capname = strdup(optarg); -+ if (event_aa_capname == NULL) -+ retval = -1; -+ c++; -+ } -+ break; -+ case S_AA_ERROR: -+ if (!optarg) { -+ fprintf(stderr, -+ "Argument is required for %s\n", -+ vars[c]); -+ retval = -1; -+ break; -+ } -+ if (isdigit(optarg[0])) { -+ errno = 0; -+ event_aa_error = strtol(optarg, NULL, 10); -+ if (errno) -+ retval = -1; -+ c++; -+ } else { -+ fprintf(stderr, -+ "error must be a numeric value, was %s\n", -+ optarg); -+ retval = -1; -+ } -+ break; -+ case S_AA_NAMESPACE: -+ if (!optarg) { -+ fprintf(stderr, -+ "Argument is required for %s\n", -+ vars[c]); -+ retval = -1; -+ } else { -+ event_aa_namespace = strdup(optarg); -+ if (event_aa_namespace == NULL) -+ retval = -1; -+ c++; -+ } -+ break; -+ case S_AA_RLIMIT: -+ if (!optarg) { -+ fprintf(stderr, -+ "Argument is required for %s\n", -+ vars[c]); -+ retval = -1; -+ } else { -+ event_aa_rlimit = strdup(optarg); -+ if (event_aa_rlimit == NULL) -+ retval = -1; -+ c++; -+ } -+ break; -+ case S_AA_LADDR: -+ if (!optarg) { -+ fprintf(stderr, -+ "Argument is required for %s\n", -+ vars[c]); -+ retval = -1; -+ } else { -+ event_aa_laddr = strdup(optarg); -+ if (event_aa_laddr == NULL) -+ retval = -1; -+ c++; -+ } -+ break; -+ case S_AA_FADDR: -+ if (!optarg) { -+ fprintf(stderr, -+ "Argument is required for %s\n", -+ vars[c]); -+ retval = -1; -+ } else { -+ event_aa_faddr = strdup(optarg); -+ if (event_aa_faddr == NULL) -+ retval = -1; -+ c++; -+ } -+ break; -+ case S_AA_LPORT: -+ if (!optarg) { -+ fprintf(stderr, -+ "Argument is required for %s\n", -+ vars[c]); -+ retval = -1; -+ break; -+ } -+ if (isdigit(optarg[0])) { -+ errno = 0; -+ event_aa_lport = strtol(optarg, NULL, 10); -+ if (errno) -+ retval = -1; -+ c++; -+ } else { -+ fprintf(stderr, -+ "lport must be a numeric value, was %s\n", -+ optarg); -+ retval = -1; -+ } -+ break; -+ case S_AA_FPORT: -+ if (!optarg) { -+ fprintf(stderr, -+ "Argument is required for %s\n", -+ vars[c]); -+ retval = -1; -+ break; -+ } -+ if (isdigit(optarg[0])) { -+ errno = 0; -+ event_aa_fport = strtol(optarg, NULL, 10); -+ if (errno) -+ retval = -1; -+ c++; -+ } else { -+ fprintf(stderr, -+ "fport must be a numeric value, was %s\n", -+ optarg); -+ retval = -1; -+ } -+ break; -+ case S_AA_FAMILY: -+ if (!optarg) { -+ fprintf(stderr, -+ "Argument is required for %s\n", -+ vars[c]); -+ retval = -1; -+ } else { -+ event_aa_family = strdup(optarg); -+ if (event_aa_family == NULL) -+ retval = -1; -+ c++; -+ } -+ break; -+ case S_AA_SOCK_TYPE: -+ if (!optarg) { -+ fprintf(stderr, -+ "Argument is required for %s\n", -+ vars[c]); -+ retval = -1; -+ } else { -+ event_aa_sock_type = strdup(optarg); -+ if (event_aa_sock_type == NULL) -+ retval = -1; -+ c++; -+ } -+ break; -+ case S_AA_PROTOCOL: -+ if (!optarg) { -+ fprintf(stderr, -+ "Argument is required for %s\n", -+ vars[c]); -+ retval = -1; -+ break; -+ } -+ if (isdigit(optarg[0])) { -+ errno = 0; -+ event_aa_protocol = strtol(optarg, NULL, 10); -+ if (errno) -+ retval = -1; -+ c++; -+ } else { -+ fprintf(stderr, -+ "protocol must be a numeric value, was %s\n", -+ optarg); -+ retval = -1; -+ } -+ break; - default: - fprintf(stderr, "%s is an unsupported option\n", - vars[c]); -diff --git a/src/ausearch-parse.c b/src/ausearch-parse.c -index 08fa2be..55175b6 100644 ---- a/src/ausearch-parse.c -+++ b/src/ausearch-parse.c -@@ -1366,6 +1366,461 @@ static int parse_integrity(const lnode *n, search_items *s) - return 0; - } - -+/* -+ * Parse AppArmor specific fields. -+ * Note that this must be done before parsing all SELinux and common fields -+ * in parse_avc(), because parse_avc() relies on specific ordering of the -+ * fields and once it parses one, it doesn't look behind for other fields. -+ * This makes it complex to parse AppArmor fields, since many appear in -+ * the middle of common fields. So to make this AppArmor support simpler -+ * to maintain, move the parsing to a dedicate function that doesn't move -+ * the current "cursor" in the log line and doesn't depend on specific -+ * orderings. -+ */ -+static int parse_avc_apparmor_fields(char *term, search_items *s) -+{ -+ char *str; -+ char *tmp = term; -+ -+ if (event_aa_apparmor) { -+ str = strstr(term, "apparmor="); -+ if (str) { -+ str += 9; -+ if (*str != '"') -+ return 100; -+ str++; -+ term = strchr(str, '"'); -+ if (term == NULL) -+ return 100; -+ *term = 0; -+ s->aa_apparmor = strdup(str); -+ *term = '"'; -+ if (s->aa_apparmor == NULL) -+ return 100; -+ term = tmp; -+ } -+ } -+ -+ if (event_aa_operation) { -+ str = strstr(term, "operation="); -+ if (str) { -+ str += 10; -+ if (*str != '"') -+ return 101; -+ str++; -+ term = strchr(str, '"'); -+ if (term == NULL) -+ return 101; -+ *term = 0; -+ s->aa_operation = strdup(str); -+ *term = '"'; -+ if (s->aa_operation == NULL) -+ return 101; -+ term = tmp; -+ } -+ } -+ -+ if (event_aa_profile) { -+ str = strstr(term, "profile="); -+ if (str) { -+ str += 8; -+ if (*str != '"') -+ return 102; -+ str++; -+ term = strchr(str, '"'); -+ if (term == NULL) -+ return 102; -+ *term = 0; -+ s->aa_profile = strdup(str); -+ *term = '"'; -+ if (s->aa_profile == NULL) -+ return 102; -+ term = tmp; -+ } -+ } -+ -+ if (event_aa_parent != -1) { -+ str = strstr(term, "parent="); -+ if (str) { -+ str += 7; -+ term = strchr(str, ' '); -+ errno = 0; -+ if (term) { -+ /* We aren't the last field in the line. */ -+ *term = 0; -+ s->aa_parent = strtoul(str, NULL, 10); -+ *term = ' '; -+ } else { -+ /* We are the last field in the line. */ -+ s->aa_parent = strtoul(str, NULL, 10); -+ } -+ if (errno) -+ return 103; -+ term = tmp; -+ } -+ } -+ -+ if (event_aa_requested_mask) { -+ str = strstr(term, "requested_mask="); -+ if (str) { -+ str += 15; -+ if (*str != '"') -+ return 104; -+ str++; -+ term = strchr(str, '"'); -+ if (term == NULL) -+ return 104; -+ *term = 0; -+ s->aa_requested_mask = strdup(str); -+ *term = '"'; -+ if (s->aa_requested_mask == NULL) -+ return 104; -+ term = tmp; -+ } -+ } -+ -+ if (event_aa_denied_mask) { -+ str = strstr(term, "denied_mask="); -+ if (str) { -+ str += 12; -+ if (*str != '"') -+ return 105; -+ str++; -+ term = strchr(str, '"'); -+ if (term == NULL) -+ return 105; -+ *term = 0; -+ s->aa_denied_mask = strdup(str); -+ *term = '"'; -+ if (s->aa_denied_mask == NULL) -+ return 105; -+ term = tmp; -+ } -+ } -+ -+ if (event_aa_fsuid != -1) { -+ str = strstr(term, "fsuid="); -+ if (str) { -+ str += 6; -+ term = strchr(str, ' '); -+ errno = 0; -+ if (term) { -+ /* We aren't the last field in the line. */ -+ *term = 0; -+ s->aa_fsuid = strtoul(str, NULL, 10); -+ *term = ' '; -+ } else { -+ /* We are the last field in the line. */ -+ s->aa_fsuid = strtoul(str, NULL, 10); -+ } -+ if (errno) -+ return 106; -+ term = tmp; -+ } -+ } -+ -+ if (event_aa_ouid != -1) { -+ str = strstr(term, "ouid="); -+ if (str) { -+ str += 5; -+ term = strchr(str, ' '); -+ errno = 0; -+ if (term) { -+ /* We aren't the last field in the line. */ -+ *term = 0; -+ s->aa_ouid = strtoul(str, NULL, 10); -+ *term = ' '; -+ } else { -+ /* We are the last field in the line. */ -+ s->aa_ouid = strtoul(str, NULL, 10); -+ } -+ if (errno) -+ return 107; -+ term = tmp; -+ } -+ } -+ -+ if (event_aa_target) { -+ str = strstr(term, "target="); -+ if (str) { -+ str += 7; -+ if (*str != '"') -+ return 108; -+ str++; -+ term = strchr(str, '"'); -+ if (term == NULL) -+ return 108; -+ *term = 0; -+ s->aa_target = strdup(str); -+ *term = '"'; -+ if (s->aa_target == NULL) -+ return 108; -+ term = tmp; -+ } -+ } -+ -+ if (event_aa_info) { -+ str = strstr(term, "info="); -+ if (str) { -+ str += 5; -+ if (*str != '"') -+ return 109; -+ str++; -+ term = strchr(str, '"'); -+ if (term == NULL) -+ return 109; -+ *term = 0; -+ s->aa_info = strdup(str); -+ *term = '"'; -+ if (s->aa_info == NULL) -+ return 109; -+ term = tmp; -+ } -+ } -+ -+ if (event_aa_capname) { -+ str = strstr(term, "capname="); -+ if (str) { -+ str += 8; -+ if (*str != '"') -+ return 110; -+ str++; -+ term = strchr(str, '"'); -+ if (term == NULL) -+ return 110; -+ *term = 0; -+ s->aa_capname = strdup(str); -+ *term = '"'; -+ if (s->aa_capname == NULL) -+ return 110; -+ term = tmp; -+ } -+ } -+ -+ if (event_aa_error != -1) { -+ str = strstr(term, "error="); -+ if (str) { -+ str += 6; -+ term = strchr(str, ' '); -+ errno = 0; -+ if (term) { -+ /* We aren't the last field in the line. */ -+ *term = 0; -+ s->aa_error = strtoul(str, NULL, 10); -+ *term = ' '; -+ } else { -+ /* We are the last field in the line. */ -+ s->aa_error = strtoul(str, NULL, 10); -+ } -+ if (errno) -+ return 111; -+ term = tmp; -+ } -+ } -+ -+ if (event_aa_namespace) { -+ str = strstr(term, "namespace="); -+ if (str) { -+ str += 10; -+ if (*str != '"') -+ return 112; -+ str++; -+ term = strchr(str, '"'); -+ if (term == NULL) -+ return 112; -+ *term = 0; -+ s->aa_namespace = strdup(str); -+ *term = '"'; -+ if (s->aa_namespace == NULL) -+ return 112; -+ term = tmp; -+ } -+ } -+ -+ if (event_aa_rlimit) { -+ str = strstr(term, "rlimit="); -+ if (str) { -+ str += 7; -+ term = strchr(str, ' '); -+ if (term) { -+ /* We aren't the last field in the line. */ -+ *term = 0; -+ s->aa_rlimit = strdup(str); -+ *term = ' '; -+ } else { -+ /* We are the last field in the line. */ -+ s->aa_rlimit = strdup(str); -+ } -+ if (s->aa_rlimit == NULL) -+ return 113; -+ term = tmp; -+ } -+ } -+ -+ if (event_aa_laddr) { -+ str = strstr(term, "laddr="); -+ if (str) { -+ str += 6; -+ if (*str == '"') { -+ str++; -+ term = strchr(str, '"'); -+ if (term == NULL) -+ return 114; -+ *term = 0; -+ s->aa_laddr = strdup(str); -+ *term = '"'; -+ } else { -+ term = strchr(str, ' '); -+ if (term) { -+ /* We aren't the last field in the line. */ -+ *term = 0; -+ s->aa_laddr = strdup(str); -+ *term = ' '; -+ } else { -+ /* We are the last field in the line. */ -+ s->aa_laddr = strdup(str); -+ } -+ } -+ if (s->aa_laddr == NULL) -+ return 114; -+ term = tmp; -+ } -+ } -+ -+ if (event_aa_faddr) { -+ str = strstr(term, "faddr="); -+ if (str) { -+ str += 6; -+ if (*str == '"') { -+ str++; -+ term = strchr(str, '"'); -+ if (term == NULL) -+ return 115; -+ *term = 0; -+ s->aa_faddr = strdup(str); -+ *term = '"'; -+ } else { -+ term = strchr(str, ' '); -+ if (term) { -+ /* We aren't the last field in the line. */ -+ *term = 0; -+ s->aa_faddr = strdup(str); -+ *term = ' '; -+ } else { -+ /* We are the last field in the line. */ -+ s->aa_faddr = strdup(str); -+ } -+ } -+ if (s->aa_faddr == NULL) -+ return 115; -+ term = tmp; -+ } -+ } -+ -+ if (event_aa_lport != -1) { -+ str = strstr(term, "lport="); -+ if (str) { -+ str += 6; -+ term = strchr(str, ' '); -+ errno = 0; -+ if (term) { -+ /* We aren't the last field in the line. */ -+ *term = 0; -+ s->aa_lport = strtoul(str, NULL, 10); -+ *term = ' '; -+ } else { -+ /* We are the last field in the line. */ -+ s->aa_lport = strtoul(str, NULL, 10); -+ } -+ if (errno) -+ return 116; -+ term = tmp; -+ } -+ } -+ -+ if (event_aa_fport != -1) { -+ str = strstr(term, "fport="); -+ if (str) { -+ str += 6; -+ term = strchr(str, ' '); -+ errno = 0; -+ if (term) { -+ /* We aren't the last field in the line. */ -+ *term = 0; -+ s->aa_fport = strtoul(str, NULL, 10); -+ *term = ' '; -+ } else { -+ /* We are the last field in the line. */ -+ s->aa_fport = strtoul(str, NULL, 10); -+ } -+ if (errno) -+ return 117; -+ term = tmp; -+ } -+ } -+ -+ if (event_aa_family) { -+ str = strstr(term, "family="); -+ if (str) { -+ str += 7; -+ if (*str != '"') -+ return 118; -+ str++; -+ term = strchr(str, '"'); -+ if (term == NULL) -+ return 118; -+ *term = 0; -+ s->aa_family = strdup(str); -+ *term = '"'; -+ if (s->aa_family == NULL) -+ return 118; -+ term = tmp; -+ } -+ } -+ -+ if (event_aa_sock_type) { -+ str = strstr(term, "sock_type="); -+ if (str) { -+ str += 10; -+ if (*str != '"') -+ return 119; -+ str++; -+ term = strchr(str, '"'); -+ if (term == NULL) -+ return 119; -+ *term = 0; -+ s->aa_sock_type = strdup(str); -+ *term = '"'; -+ if (s->aa_sock_type == NULL) -+ return 119; -+ term = tmp; -+ } -+ } -+ -+ if (event_aa_protocol != -1) { -+ str = strstr(term, "protocol="); -+ if (str) { -+ str += 9; -+ term = strchr(str, ' '); -+ errno = 0; -+ if (term) { -+ /* We aren't the last field in the line. */ -+ *term = 0; -+ s->aa_protocol = strtoul(str, NULL, 10); -+ *term = ' '; -+ } else { -+ /* We are the last field in the line. */ -+ s->aa_protocol = strtoul(str, NULL, 10); -+ } -+ if (errno) -+ return 120; -+ term = tmp; -+ } -+ } -+ -+ return 0; -+} -+ - - /* FIXME: If they are in permissive mode or hit an auditallow, there can - * be more that 1 avc in the same syscall. For now, we pickup just the first. -@@ -1379,6 +1834,10 @@ static int parse_avc(const lnode *n, search_items *s) - term = n->message; - anode_init(&an); - -+ rc = parse_avc_apparmor_fields(term, s); -+ if (rc) -+ goto err; -+ - // get the avc message info. - str = strstr(term, "avc: "); - if (str) { --- -1.8.4.5 - diff --git a/audit-secondary.spec b/audit-secondary.spec index 8c8865c..e9f81a9 100644 --- a/audit-secondary.spec +++ b/audit-secondary.spec @@ -1,7 +1,7 @@ # # spec file for package audit-secondary # -# Copyright (c) 2015 SUSE LINUX Products GmbH, Nuernberg, Germany. +# Copyright (c) 2014 SUSE LINUX Products GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -39,7 +39,6 @@ Patch2: audit-no-gss.patch Patch3: audit-no_m4_dir.patch Patch4: audit-allow-manual-stop.patch Patch5: audit-ausearch-do-not-require-tclass.patch -Patch6: audit-ausearch-filter-apparmor-events.patch BuildRoot: %{_tmppath}/%{name}-%{version}-build BuildRequires: audit-devel = %{version} BuildRequires: autoconf >= 2.12 @@ -97,7 +96,6 @@ rm -rf audisp/plugins/prelude %patch3 -p1 %patch4 -p1 %patch5 -p1 -%patch6 -p1 %build autoreconf -fi export CFLAGS="%{optflags} -fno-strict-aliasing" diff --git a/audit.changes b/audit.changes index 5426ede..00380d9 100644 --- a/audit.changes +++ b/audit.changes @@ -1,9 +1,3 @@ -------------------------------------------------------------------- -Thu Jan 29 12:17:30 UTC 2015 - fdmanana@suse.com - -- Teach ausearch to filter AppArmor events (Fate#317726). - Added patch file audit-ausearch-filter-apparmor-events.patch - ------------------------------------------------------------------- Mon Nov 24 14:55:22 UTC 2014 - mq@suse.cz diff --git a/audit.spec b/audit.spec index aee5b1f..269c3c0 100644 --- a/audit.spec +++ b/audit.spec @@ -1,7 +1,7 @@ # # spec file for package audit # -# Copyright (c) 2015 SUSE LINUX Products GmbH, Nuernberg, Germany. +# Copyright (c) 2014 SUSE LINUX Products GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed From 7a17f4104f0458b20ea07a491c5ba375db8cdd9895b30785a517f3e7635610d7 Mon Sep 17 00:00:00 2001 From: Tony Jones Date: Fri, 4 Sep 2015 22:09:27 +0000 Subject: [PATCH 3/4] Accepting request 329223 from home:jones_tony:branches:security OBS-URL: https://build.opensuse.org/request/show/329223 OBS-URL: https://build.opensuse.org/package/show/security/audit?expand=0&rev=78 --- audit-2.4.1.tar.gz | 3 --- audit-2.4.4.tar.gz | 3 +++ audit-secondary.changes | 12 +++++++++++ audit-secondary.spec | 40 +++++++++++++++++++++++------------ audit.changes | 47 +++++++++++++++++++++++++++++++++++++++++ audit.spec | 8 +++---- 6 files changed, 92 insertions(+), 21 deletions(-) delete mode 100644 audit-2.4.1.tar.gz create mode 100644 audit-2.4.4.tar.gz diff --git a/audit-2.4.1.tar.gz b/audit-2.4.1.tar.gz deleted file mode 100644 index 8be2c45..0000000 --- a/audit-2.4.1.tar.gz +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:059346fa0e922faf4dcc054382b21f4845cd8c4942e82cfd0d4cd52bd2b03026 -size 942147 diff --git a/audit-2.4.4.tar.gz b/audit-2.4.4.tar.gz new file mode 100644 index 0000000..e2df874 --- /dev/null +++ b/audit-2.4.4.tar.gz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:25f57f465f3230d7b1166b615ffd6748818a3dc225d0e8b396c5b2e951674e23 +size 1004024 diff --git a/audit-secondary.changes b/audit-secondary.changes index 375b6a0..90810cd 100644 --- a/audit-secondary.changes +++ b/audit-secondary.changes @@ -1,3 +1,15 @@ +------------------------------------------------------------------- +Fri Aug 21 19:00:36 UTC 2015 - tonyj@suse.com + +- Update to version 2.4.4. See audit.spec (libaudit1) for upstream + changelog +- Add python3 bindings for libaudit and libauparse +- Remove patch 'audit-no_m4_dir.patch' + (added Fri Apr 26 11:14:39 UTC 2013 by mmeister@suse.com) + No idea what earlier 'automake' build error this was trying to fix but + it broke the handling of "--without-libcap-ng". Anyways, no build error + occurs now and m4 path is also needed in v2.4.4 to find ax_prog_cc_for_build + ------------------------------------------------------------------- Tue Sep 2 17:35:12 UTC 2014 - tonyj@suse.com diff --git a/audit-secondary.spec b/audit-secondary.spec index e9f81a9..9483702 100644 --- a/audit-secondary.spec +++ b/audit-secondary.spec @@ -1,7 +1,7 @@ # # spec file for package audit-secondary # -# Copyright (c) 2014 SUSE LINUX Products GmbH, Nuernberg, Germany. +# Copyright (c) 2015 SUSE LINUX GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -26,19 +26,19 @@ BuildRequires: gcc-c++ BuildRequires: openldap2-devel BuildRequires: pkg-config BuildRequires: python-devel +BuildRequires: python3-devel BuildRequires: swig Summary: Secondary packages for audit License: GPL-2.0+ Group: System/Monitoring -Version: 2.4.1 +Version: 2.4.4 Release: 0 Url: http://people.redhat.com/sgrubb/audit/ Source0: http://people.redhat.com/sgrubb/audit/%{_name}-%{version}.tar.gz Patch1: audit-plugins-path.patch Patch2: audit-no-gss.patch -Patch3: audit-no_m4_dir.patch -Patch4: audit-allow-manual-stop.patch -Patch5: audit-ausearch-do-not-require-tclass.patch +Patch3: audit-allow-manual-stop.patch +Patch4: audit-ausearch-do-not-require-tclass.patch BuildRoot: %{_tmppath}/%{name}-%{version}-build BuildRequires: audit-devel = %{version} BuildRequires: autoconf >= 2.12 @@ -75,6 +75,16 @@ Group: System/Monitoring The audit-libs-python package contains the bindings for using libaudit by python. +%package -n audit-libs-python3 +Summary: Python3 Bindings for libaudit +License: LGPL-2.1+ +Group: System/Monitoring +%py_requires + +%description -n audit-libs-python3 +The audit-libs-python3 package contains the bindings for using libaudit +by python3. + %package -n audit-audispd-plugins Summary: Default plugins for the audit dispatcher License: GPL-2.0+ @@ -95,7 +105,6 @@ rm -rf audisp/plugins/prelude %patch2 -p1 %patch3 -p1 %patch4 -p1 -%patch5 -p1 %build autoreconf -fi export CFLAGS="%{optflags} -fno-strict-aliasing" @@ -131,14 +140,11 @@ rm -rf $RPM_BUILD_ROOT/etc/rc.d/init.d # https://lists.fedoraproject.org/pipermail/devel/2012-June/169411.html rm -rf $RPM_BUILD_ROOT/usr/lib/audit # Clean up some unneeded library files -rm -f $RPM_BUILD_ROOT/%{_libdir}/python%{py_ver}/site-packages/_audit.a -rm -f $RPM_BUILD_ROOT/%{_libdir}/python%{py_ver}/site-packages/_audit.la -rm -f $RPM_BUILD_ROOT/%{_libdir}/python%{py_ver}/site-packages/_auparse.a -rm -f $RPM_BUILD_ROOT/%{_libdir}/python%{py_ver}/site-packages/_auparse.la -rm -f $RPM_BUILD_ROOT/%{_libdir}/python%{py_ver}/site-packages/auparse.a -rm -f $RPM_BUILD_ROOT/%{_libdir}/python%{py_ver}/site-packages/auparse.la -rm -f $RPM_BUILD_ROOT/%{_libdir}/python%{py_ver}/site-packages/auparse-1.0-py%{py_ver}.egg-info -rm -f $RPM_BUILD_ROOT/%{_libdir}/pkgconfig/audit.pc +for ver in %{py_ver} %{py3_ver}; do + rm -f $RPM_BUILD_ROOT/%{_libdir}/python${ver}/site-packages/{_audit,_auparse,auparse}.{a,la} + rm -f $RPM_BUILD_ROOT/%{_libdir}/python${ver}/site-packages/auparse-1.0-py${ver}.egg-info +done +rm -f $RPM_BUILD_ROOT/%{_libdir}/pkgconfig/{audit,auparse}.pc # cleanup files handled by audit.spec rm -rf $RPM_BUILD_ROOT/%{_includedir} rm -f $RPM_BUILD_ROOT/%{_libdir}/lib{audit,auparse}.* @@ -243,6 +249,12 @@ fi %attr(755,root,root) %{_libdir}/python%{py_ver}/site-packages/auparse.so %{_libdir}/python%{py_ver}/site-packages/audit.py* +%files -n audit-libs-python3 +%defattr(-,root,root,-) +%attr(755,root,root) %{_libdir}/python%{py3_ver}/site-packages/_audit.so +%attr(755,root,root) %{_libdir}/python%{py3_ver}/site-packages/auparse.so +%{_libdir}/python%{py3_ver}/site-packages/audit.py* + %files -n audit-audispd-plugins %defattr(-,root,root,-) %attr(644,root,root) %{_mandir}/man8/audispd-zos-remote.8.gz diff --git a/audit.changes b/audit.changes index 00380d9..a5e6fa9 100644 --- a/audit.changes +++ b/audit.changes @@ -1,3 +1,50 @@ +------------------------------------------------------------------- +Fri Aug 21 18:58:18 UTC 2015 - tonyj@suse.com + +- Update to version 2.4.4 (bsc#941922, CVE-2015-5186) +- Remove patch 'audit-no_m4_dir.patch' + (added Fri Apr 26 11:14:39 UTC 2013 by mmeister@suse.com) + No idea what earlier 'automake' build error this was trying to fix but + it broke the handling of "--without-libcap-ng". Anyways, no build error + occurs now and m4 path is also needed in v2.4.4 to find ax_prog_cc_for_build +- Require pkgconfig for build + + Changelog 2.4.4 + - Fix linked list correctness in ausearch/report + - Add more cross compile fixups (Clayton Shotwell) + - Update auparse python bindings + - Update libev to 4.20 + - Fix CVE-2015-5186 Audit: log terminal emulator escape sequences handling + + Changelog 2.4.3 + - Add python3 support for libaudit + - Cleanup automake warnings + - Add AuParser_search_add_timestamp_item_ex to python bindings + - Add AuParser_get_type_name to python bindings + - Correct processing of obj_gid in auditctl (Aleksander Zdyb) + - Make plugin config file parsing more robust for long lines (#1235457) + - Make auditctl status print lost field as unsigned number + - Add interpretation mode for auditctl -s + - Add python3 support to auparse library + - Make --enable-zos-remote a build time configuration option (Clayton Shotwell) + - Updates for cross compiling (Clayton Shotwell) + - Add MAC_CHECK audit event type + - Add libauparse pkgconfig file (Aleksander Zdyb) + + Changelog 2.4.2 + - Ausearch should parse exe field in SECCOMP events + - Improve output for short mode interpretations in auparse + - Add CRYPTO_IKE_SA and CRYPTO_IPSEC_SA events + - If auditctl is reading rules from a file, send messages to syslog (#1144252) + - Correct lookup of ppc64le when determining machine type + - Increase time buffer for wide character numbers in ausearch/report (#1200314) + - In aureport, add USER_TTY events to tty report + - In audispd, limit reporting of queue full messages (#1203810) + - In auditctl, don't segfault when invalid options passed (#1206516) + - In autrace, remove some older unimplemented syscalls for aarch64 (#1185892) + - In auditctl, correct lookup of aarch64 in arch field (#1186313) + - Update lookup tables for 4.1 kernel + ------------------------------------------------------------------- Mon Nov 24 14:55:22 UTC 2014 - mq@suse.cz diff --git a/audit.spec b/audit.spec index 269c3c0..7bdb0a8 100644 --- a/audit.spec +++ b/audit.spec @@ -1,7 +1,7 @@ # # spec file for package audit # -# Copyright (c) 2014 SUSE LINUX Products GmbH, Nuernberg, Germany. +# Copyright (c) 2015 SUSE LINUX GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -20,18 +20,18 @@ Name: audit Summary: First part of auditing package License: GPL-2.0+ Group: System/Monitoring -Version: 2.4.1 +Version: 2.4.4 Release: 0 Url: http://people.redhat.com/sgrubb/audit/ Source0: http://people.redhat.com/sgrubb/audit/%{name}-%{version}.tar.gz Source1: baselibs.conf Source2: README-BEFORE-ADDING-PATCHES -Patch1: audit-no_m4_dir.patch BuildRoot: %{_tmppath}/%{name}-%{version}-build BuildRequires: autoconf >= 2.12 BuildRequires: gcc-c++ BuildRequires: kernel-headers >= 2.6.30 BuildRequires: libtool +BuildRequires: pkgconfig BuildRequires: tcpd-devel Requires: %{name}-libs = %{version} PreReq: %insserv_prereq %fillup_prereq @@ -75,7 +75,6 @@ libraries. %prep %setup -q -n %{name}-%{version} -%patch1 -p1 %build autoreconf -fi @@ -138,5 +137,6 @@ install -m 0644 init.d/libaudit.conf $RPM_BUILD_ROOT/etc %{_includedir}/auparse-defs.h %{_mandir}/man3/* %{_libdir}/pkgconfig/audit.pc +%{_libdir}/pkgconfig/auparse.pc %changelog From b5e111de83c16e422fdc73657c5624655835fc0b357414cea4a8d69d18909a1c Mon Sep 17 00:00:00 2001 From: Tony Jones Date: Fri, 4 Sep 2015 22:54:46 +0000 Subject: [PATCH 4/4] OBS-URL: https://build.opensuse.org/package/show/security/audit?expand=0&rev=79 --- audit-no_m4_dir.patch | 15 --------------- 1 file changed, 15 deletions(-) delete mode 100644 audit-no_m4_dir.patch diff --git a/audit-no_m4_dir.patch b/audit-no_m4_dir.patch deleted file mode 100644 index bb2e5ce..0000000 --- a/audit-no_m4_dir.patch +++ /dev/null @@ -1,15 +0,0 @@ -From: Maximilian Meister -Subject: Remove AC_CONFIG_MACRO_DIR([m4]) from configure.ac - -audit cannnot build with automake-1.13.1 when looking for a m4 directory - ---- a/configure.ac 2013-04-26 13:09:46.019388414 +0200 -+++ b/configure.ac 2013-04-26 13:10:54.607385058 +0200 -@@ -35,7 +35,6 @@ - - echo Configuring auditd $VERSION - --AC_CONFIG_MACRO_DIR([m4]) - AC_CANONICAL_TARGET - AM_INIT_AUTOMAKE - AM_PROG_LIBTOOL