New upstream version 3.0.6
Laurent Bigonville
2 years ago
0 | 3.0.6 | |
1 | - Fixed various issues when dealing with corrupted logs | |
2 | - Make IPX packet interpretation dependent on the ipx header file existing | |
3 | - Add b32/b64 support to ausyscall (Egor Ignatov) | |
4 | - Add support for armv8l (Egor Ignatov) | |
5 | - Fix auditctl list of syscalls in PPC (Egor Ignatov) | |
6 | - auditd.service now restarts auditd under some conditions (Timothée Ravier) | |
7 | ||
0 | 8 | 3.0.5 |
1 | 9 | - In auditd, flush uid/gid caches when user/group added/deleted/modified |
2 | 10 | - Fixed various issues when dealing with corrupted logs |
7 | 7 | |
8 | 8 | BUILDING |
9 | 9 | ======== |
10 | See the README-install File. | |
10 | See the Install(.tmp) file. | |
11 | 11 | |
12 | 12 | USAGE |
13 | 13 | ===== |
3 | 3 | * Basic HIDS based on reactive audit component |
4 | 4 | * Add keywords for time: month-ago, this-hour, last-hour |
5 | 5 | * If searching user/group doesn't map to uid/gid, do translated string search |
6 | * In audispd, look into non-blocking handling of write to plugins | |
6 | * In auditd, look into non-blocking handling of write to plugins | |
7 | 7 | * Support multiple time streams when searching |
8 | 8 | |
9 | 9 | 3.1.1 |
0 | 0 | |
1 | 1 | Summary: User space tools for kernel auditing |
2 | 2 | Name: audit |
3 | Version: 3.0.5 | |
3 | Version: 3.0.6 | |
4 | 4 | Release: 1%{dist} |
5 | 5 | License: GPLv2+ |
6 | 6 | Group: System Environment/Daemons |
255 | 255 | |
256 | 256 | |
257 | 257 | %changelog |
258 | * Wed Aug 11 2021 Steve Grubb <sgrubb@redhat.com> 3.0.5-1 | |
258 | * Fri Oct 01 2021 Steve Grubb <sgrubb@redhat.com> 3.0.6-1 | |
259 | 259 | - New upstream release |
260 | 260 |
1201 | 1201 | // at this point we have type= |
1202 | 1202 | ptr = audit_strsplit(NULL); |
1203 | 1203 | // strlen is for fuzzers that make invalid lines |
1204 | if (ptr && strnlen(ptr, 28) > 24) { | |
1204 | if (ptr && strnlen(ptr, 20) > 18) { | |
1205 | 1205 | if (*(ptr+9) == '(') |
1206 | 1206 | ptr+=9; |
1207 | 1207 | else |
1581 | 1581 | if (debug) |
1582 | 1582 | printf("Adding event to building event\n"); |
1583 | 1583 | #endif /* LOL_EVENTS_DEBUG01 */ |
1584 | aup_list_append(cur->l, au->cur_buf, | |
1585 | au->list_idx, au->line_number); | |
1584 | if (aup_list_append(cur->l, au->cur_buf, | |
1585 | au->list_idx, au->line_number) < 0) { | |
1586 | au->cur_buf = NULL; | |
1587 | continue; | |
1588 | } | |
1586 | 1589 | au->cur_buf = NULL; |
1587 | 1590 | free((char *)e.host); |
1588 | 1591 | au_check_events(au, e.sec); |
102 | 102 | static int parse_up_record(rnode* r) |
103 | 103 | { |
104 | 104 | char *ptr, *buf, *saved=NULL; |
105 | unsigned int offset = 0; | |
105 | unsigned int offset = 0, len; | |
106 | 106 | |
107 | 107 | // Potentially cut the record in two |
108 | 108 | ptr = strchr(r->record, AUDIT_INTERP_SEPARATOR); |
111 | 111 | ptr++; |
112 | 112 | } |
113 | 113 | r->interp = ptr; |
114 | r->nv.record = buf = strdup(r->record); | |
114 | // Rather than call strndup, we will do it ourselves to reduce | |
115 | // the number of interations across the record. | |
116 | // len includes the string terminator. | |
117 | len = strlen(r->record) + 1; | |
118 | r->nv.record = buf = malloc(len); | |
119 | if (r->nv.record == NULL) | |
120 | return -1; | |
121 | memcpy(r->nv.record, r->record, len); | |
122 | r->nv.end = r->nv.record + len; | |
115 | 123 | ptr = audit_strsplit_r(buf, &saved); |
116 | 124 | if (ptr == NULL) { |
117 | 125 | free(buf); |
126 | r->nv.record = NULL; | |
118 | 127 | return -1; |
119 | 128 | } |
120 | 129 | |
321 | 330 | // If for some reason it was useless, delete buf |
322 | 331 | if (r->nv.cnt == 0) { |
323 | 332 | free(buf); |
333 | r->nv.record = NULL; | |
334 | r->nv.end = NULL; | |
324 | 335 | free((void *)r->cwd); |
325 | 336 | } |
326 | 337 |
43 | 43 | #include <linux/ax25.h> |
44 | 44 | #include <linux/atm.h> |
45 | 45 | #include <linux/x25.h> |
46 | #include <linux/if.h> // FIXME: remove when ipx.h is fixed | |
47 | #include <linux/ipx.h> | |
46 | #ifdef HAVE_IPX_HEADERS | |
47 | #include <linux/if.h> // FIXME: remove when ipx.h is fixed | |
48 | #include <linux/ipx.h> | |
49 | #endif | |
48 | 50 | #include <linux/capability.h> |
49 | 51 | #include <sys/personality.h> |
50 | 52 | #include <sys/prctl.h> |
838 | 840 | static char *print_escaped(const char *val) |
839 | 841 | { |
840 | 842 | char *out; |
843 | ||
844 | if (val == NULL) | |
845 | return strdup(" "); | |
841 | 846 | |
842 | 847 | if (*val == '"') { |
843 | 848 | char *term; |
1275 | 1280 | x->sax25_call.ax25_call[6]); |
1276 | 1281 | } |
1277 | 1282 | break; |
1283 | #ifdef HAVE_IPX_HEADERS | |
1278 | 1284 | case AF_IPX: |
1279 | 1285 | { |
1280 | 1286 | const struct sockaddr_ipx *ip = |
1284 | 1290 | str, ip->sipx_port, ip->sipx_network); |
1285 | 1291 | } |
1286 | 1292 | break; |
1293 | #endif | |
1287 | 1294 | case AF_ATMPVC: |
1288 | 1295 | { |
1289 | 1296 | const struct sockaddr_atmpvc* at = |
35 | 35 | l->cur = 0; |
36 | 36 | l->cnt = 0; |
37 | 37 | l->record = NULL; |
38 | l->end = NULL; | |
38 | 39 | } |
39 | 40 | } |
40 | 41 | |
41 | 42 | nvnode *nvlist_next(nvlist *l) |
42 | 43 | { |
44 | // Since cur will be incremented, check for 1 less that total | |
43 | 45 | if (l->cnt && l->cur < (l->cnt - 1)) { |
44 | 46 | l->cur++; |
45 | 47 | return &l->array[l->cur]; |
118 | 120 | const char *nvlist_interp_cur_val(rnode *r, auparse_esc_t escape_mode) |
119 | 121 | { |
120 | 122 | nvlist *l = &r->nv; |
123 | if (l->cnt == 0) | |
124 | return NULL; | |
121 | 125 | nvnode *node = &l->array[l->cur]; |
122 | 126 | if (node->interp_val) |
123 | 127 | return node->interp_val; |
124 | 128 | return do_interpret(r, escape_mode); |
125 | 129 | } |
126 | 130 | |
131 | // This function determines if a chunk of memory is part of the parsed up | |
132 | // record. If it is, do not free it since it gets free'd at the very end. | |
133 | // NOTE: This function causes invalid-pointer-pair errors with ASAN | |
134 | static inline int not_in_rec_buf(nvlist *l, const char *ptr) | |
135 | { | |
136 | if (ptr >= l->record && ptr < l->end) | |
137 | return 0; | |
138 | return 1; | |
139 | } | |
140 | ||
127 | 141 | // free_interp does not apply to thing coming from interpretation_list |
128 | void nvlist_clear(nvlist* l, int free_interp) | |
142 | void nvlist_clear(nvlist *l, int free_interp) | |
129 | 143 | { |
130 | 144 | unsigned int i = 0; |
131 | register nvnode* current; | |
145 | register nvnode *current; | |
132 | 146 | |
133 | 147 | if (l->cnt == 0) |
134 | 148 | return; |
139 | 153 | free(current->interp_val); |
140 | 154 | // A couple items are not in parsed up list. |
141 | 155 | // These all come from the aup_list_append path. |
142 | if ((strcmp(current->name, "key") == 0) || | |
143 | (strcmp(current->name, "seperms") == 0) || | |
144 | (strcmp(current->name, "seresult") == 0)) { | |
156 | if (not_in_rec_buf(l, current->name)) { | |
145 | 157 | // seperms & key values are strdup'ed |
146 | if (current->name[2] != 'r') | |
158 | if (not_in_rec_buf(l, current->val)) | |
147 | 159 | free(current->val); |
148 | 160 | free(current->name); |
149 | 161 | } |
152 | 164 | } |
153 | 165 | free((void *)l->record); |
154 | 166 | l->record = NULL; |
167 | l->end = NULL; | |
155 | 168 | l->cur = 0; |
156 | 169 | l->cnt = 0; |
157 | 170 | } |
44 | 44 | AUDIT_HIDDEN_START |
45 | 45 | |
46 | 46 | void nvlist_create(nvlist *l); |
47 | void nvlist_clear(nvlist* l, int free_interp); | |
47 | void nvlist_clear(nvlist *l, int free_interp); | |
48 | 48 | nvnode *nvlist_next(nvlist *l); |
49 | 49 | int nvlist_get_cur_type(rnode *r); |
50 | 50 | const char *nvlist_interp_cur_val(rnode *r, auparse_esc_t escape_mode); |
39 | 39 | unsigned int cur; // Index to current node |
40 | 40 | unsigned int cnt; // How many items in this list |
41 | 41 | char *record; // Holds the parsed up record |
42 | char *end; // End of the parsed up record | |
42 | 43 | } nvlist; |
43 | 44 | |
44 | 45 |
42 | 42 | |
43 | 43 | /* Define to 1 if you have the <inttypes.h> header file. */ |
44 | 44 | #undef HAVE_INTTYPES_H |
45 | ||
46 | /* IPX packet interpretation */ | |
47 | #undef HAVE_IPX_HEADERS | |
45 | 48 | |
46 | 49 | /* Define to 1 if linux/fs.h defined kernel_rwf_t */ |
47 | 50 | #undef HAVE_KERNEL_RWF_T |
0 | 0 | #! /bin/sh |
1 | 1 | # From configure.ac Revision: 1.3 . |
2 | 2 | # Guess values for system-dependent variables and create Makefiles. |
3 | # Generated by GNU Autoconf 2.69 for audit 3.0.5. | |
3 | # Generated by GNU Autoconf 2.69 for audit 3.0.6. | |
4 | 4 | # |
5 | 5 | # |
6 | 6 | # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. |
587 | 587 | # Identity of this package. |
588 | 588 | PACKAGE_NAME='audit' |
589 | 589 | PACKAGE_TARNAME='audit' |
590 | PACKAGE_VERSION='3.0.5' | |
591 | PACKAGE_STRING='audit 3.0.5' | |
590 | PACKAGE_VERSION='3.0.6' | |
591 | PACKAGE_STRING='audit 3.0.6' | |
592 | 592 | PACKAGE_BUGREPORT='' |
593 | 593 | PACKAGE_URL='' |
594 | 594 | |
1397 | 1397 | # Omit some internal or obsolete options to make the list less imposing. |
1398 | 1398 | # This message is too long to be a string in the A/UX 3.1 sh. |
1399 | 1399 | cat <<_ACEOF |
1400 | \`configure' configures audit 3.0.5 to adapt to many kinds of systems. | |
1400 | \`configure' configures audit 3.0.6 to adapt to many kinds of systems. | |
1401 | 1401 | |
1402 | 1402 | Usage: $0 [OPTION]... [VAR=VALUE]... |
1403 | 1403 | |
1469 | 1469 | |
1470 | 1470 | if test -n "$ac_init_help"; then |
1471 | 1471 | case $ac_init_help in |
1472 | short | recursive ) echo "Configuration of audit 3.0.5:";; | |
1472 | short | recursive ) echo "Configuration of audit 3.0.6:";; | |
1473 | 1473 | esac |
1474 | 1474 | cat <<\_ACEOF |
1475 | 1475 | |
1595 | 1595 | test -n "$ac_init_help" && exit $ac_status |
1596 | 1596 | if $ac_init_version; then |
1597 | 1597 | cat <<\_ACEOF |
1598 | audit configure 3.0.5 | |
1598 | audit configure 3.0.6 | |
1599 | 1599 | generated by GNU Autoconf 2.69 |
1600 | 1600 | |
1601 | 1601 | Copyright (C) 2012 Free Software Foundation, Inc. |
2300 | 2300 | This file contains any messages produced by compilers while |
2301 | 2301 | running configure, to aid debugging if configure makes a mistake. |
2302 | 2302 | |
2303 | It was created by audit $as_me 3.0.5, which was | |
2303 | It was created by audit $as_me 3.0.6, which was | |
2304 | 2304 | generated by GNU Autoconf 2.69. Invocation command line was |
2305 | 2305 | |
2306 | 2306 | $ $0 $@ |
3279 | 3279 | |
3280 | 3280 | # Define the identity of the package. |
3281 | 3281 | PACKAGE='audit' |
3282 | VERSION='3.0.5' | |
3282 | VERSION='3.0.6' | |
3283 | 3283 | |
3284 | 3284 | |
3285 | 3285 | cat >>confdefs.h <<_ACEOF |
16046 | 16046 | |
16047 | 16047 | fi |
16048 | 16048 | |
16049 | # linux/ipx.h - deprecated in 2018 | |
16050 | ac_fn_c_check_header_mongrel "$LINENO" "linux/ipx.h" "ac_cv_header_linux_ipx_h" "$ac_includes_default" | |
16051 | if test "x$ac_cv_header_linux_ipx_h" = xyes; then : | |
16052 | ipx_headers=yes | |
16053 | else | |
16054 | ipx_headers=no | |
16055 | fi | |
16056 | ||
16057 | ||
16058 | if test $ipx_headers = yes ; then | |
16059 | ||
16060 | $as_echo "#define HAVE_IPX_HEADERS 1" >>confdefs.h | |
16061 | ||
16062 | fi | |
16063 | ||
16049 | 16064 | # See if we want to support lower capabilities for plugins |
16050 | 16065 | |
16051 | 16066 | |
16734 | 16749 | # report actual input values of CONFIG_FILES etc. instead of their |
16735 | 16750 | # values after options handling. |
16736 | 16751 | ac_log=" |
16737 | This file was extended by audit $as_me 3.0.5, which was | |
16752 | This file was extended by audit $as_me 3.0.6, which was | |
16738 | 16753 | generated by GNU Autoconf 2.69. Invocation command line was |
16739 | 16754 | |
16740 | 16755 | CONFIG_FILES = $CONFIG_FILES |
16800 | 16815 | cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 |
16801 | 16816 | ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" |
16802 | 16817 | ac_cs_version="\\ |
16803 | audit config.status 3.0.5 | |
16818 | audit config.status 3.0.6 | |
16804 | 16819 | configured by $0, generated by GNU Autoconf 2.69, |
16805 | 16820 | with options \\"\$ac_cs_config\\" |
16806 | 16821 |
28 | 28 | ]) |
29 | 29 | |
30 | 30 | AC_REVISION($Revision: 1.3 $)dnl |
31 | AC_INIT(audit,3.0.5) | |
31 | AC_INIT(audit,3.0.6) | |
32 | 32 | AC_PREREQ(2.12)dnl |
33 | 33 | AM_CONFIG_HEADER(config.h) |
34 | 34 | |
417 | 417 | AC_DEFINE_UNQUOTED(HAVE_LIBWRAP, [], Define if tcp_wrappers support is enabled ) |
418 | 418 | fi |
419 | 419 | |
420 | # linux/ipx.h - deprecated in 2018 | |
421 | AC_CHECK_HEADER(linux/ipx.h, ipx_headers=yes, ipx_headers=no) | |
422 | if test $ipx_headers = yes ; then | |
423 | AC_DEFINE(HAVE_IPX_HEADERS,1,[IPX packet interpretation]) | |
424 | fi | |
425 | ||
420 | 426 | # See if we want to support lower capabilities for plugins |
421 | 427 | LIBCAP_NG_PATH |
422 | 428 |
57 | 57 | /* |
58 | 58 | * SIGTERM handler |
59 | 59 | */ |
60 | static void term_handler( int sig ) | |
60 | static void term_handler(int sig) | |
61 | 61 | { |
62 | 62 | stop = 1; |
63 | 63 | } |
65 | 65 | /* |
66 | 66 | * SIGHUP handler: re-read config |
67 | 67 | */ |
68 | static void hup_handler( int sig ) | |
68 | static void hup_handler(int sig) | |
69 | 69 | { |
70 | 70 | hup = 1; |
71 | 71 | } |
73 | 73 | static void reload_config(void) |
74 | 74 | { |
75 | 75 | hup = 0; |
76 | ||
77 | /* | |
78 | * Add your code here that re-reads the config file and changes | |
79 | * how your plugin works. | |
80 | */ | |
76 | 81 | } |
77 | 82 | |
78 | 83 | int main(int argc, char *argv[]) |
260 | 260 | Any \fIsyscall name\fP or \fInumber\fP may be used. The word '\fBall\fP' may also be used. If the given syscall is made by a program, then start an audit record. If a field rule is given and no syscall is specified, it will default to all syscalls. You may also specify multiple syscalls in the same rule by using multiple \-S options in the same rule. Doing so improves performance since fewer rules need to be evaluated. Alternatively, you may pass a comma separated list of syscall names. If you are on a bi-arch system, like x86_64, you should be aware that auditctl simply takes the text, looks it up for the native arch (in this case b64) and sends that rule to the kernel. If there are no additional arch directives, IT WILL APPLY TO BOTH 32 & 64 BIT SYSCALLS. This can have undesirable effects since there is no guarantee that any syscall has the same number on both 32 and 64 bit interfaces. You will likely want to control this and write 2 rules, one with arch equal to b32 and one with b64 to make sure the kernel finds the events that you intend. See the arch field discussion for more info. |
261 | 261 | .TP |
262 | 262 | .BI \-w\ path |
263 | Insert a watch for the file system object at \fIpath\fP. You cannot insert a watch to the top level directory. This is prohibited by the kernel. Wildcards are not supported either and will generate a warning. The way that watches work is by tracking the inode internally. If you place a watch on a file, its the same as using the \-F path option on a syscall rule. If you place a watch on a directory, its the same as using the \-F dir option on a syscall rule. The \-w form of writing watches is for backwards compatibility and the syscall based form is more expressive. Unlike most syscall auditing rules, watches do not impact performance based on the number of rules sent to the kernel. The only valid options when using a watch are the \-p and \-k. If you need to anything fancy like audit a specific user accessing a file, then use the syscall auditing form with the path or dir fields. See the EXAMPLES section for an example of converting one form to another. | |
263 | Insert a watch for the file system object at \fIpath\fP. You cannot insert a watch to the top level directory. This is prohibited by the kernel. Wildcards are not supported either and will generate a warning. The way that watches work is by tracking the inode internally. If you place a watch on a file, its the same as using the \-F path option on a syscall rule. If you place a watch on a directory, its the same as using the \-F dir option on a syscall rule. The \-w form of writing watches is for backwards compatibility and the syscall based form is more expressive. Unlike most syscall auditing rules, watches do not impact performance based on the number of rules sent to the kernel. The only valid options when using a watch are the \-p and \-k. If you need to do anything fancy like audit a specific user accessing a file, then use the syscall auditing form with the path or dir fields. See the EXAMPLES section for an example of converting one form to another. | |
264 | 264 | .TP |
265 | 265 | .BI \-W\ path |
266 | 266 | Remove a watch for the file system object at \fIpath\fP. The rule must match exactly. See \fB-d\fP discussion for more info. |
0 | .TH "AUDITD" "8" "Sept 2013" "Red Hat" "System Administration Utilities" | |
0 | .TH "AUDITD" "8" "Sept 2021" "Red Hat" "System Administration Utilities" | |
1 | 1 | .SH NAME |
2 | 2 | auditd \- The Linux Audit daemon |
3 | 3 | .SH SYNOPSIS |
34 | 34 | be passed to the dispatcher. (default: /etc/audit/) |
35 | 35 | .SH SIGNALS |
36 | 36 | .TP |
37 | SIGHUP | |
37 | .B SIGHUP | |
38 | 38 | causes auditd to reconfigure. This means that auditd re-reads the configuration file. If there are no syntax errors, it will proceed to implement the requested changes. If the reconfigure is successful, a DAEMON_CONFIG event is recorded in the logs. If not successful, error handling is controlled by space_left_action, admin_space_left_action, disk_full_action, and disk_error_action parameters in auditd.conf. |
39 | 39 | |
40 | 40 | .TP |
41 | SIGTERM | |
41 | .B SIGTERM | |
42 | 42 | caused auditd to discontinue processing audit events, write a shutdown audit event, and exit. |
43 | 43 | |
44 | 44 | .TP |
45 | SIGUSR1 | |
45 | .B SIGUSR1 | |
46 | 46 | causes auditd to immediately rotate the logs. It will consult the max_log_file_action to see if it should keep the logs or not. |
47 | 47 | |
48 | 48 | .TP |
49 | SIGUSR2 | |
49 | .B SIGUSR2 | |
50 | 50 | causes auditd to attempt to resume logging and passing events to plugins. This is usually needed after logging has been suspended or the internal queue is overflowed. Either of these conditions depends on the applicable configuration settings. |
51 | 51 | .TP |
52 | SIGCONT | |
52 | .B SIGCONT | |
53 | 53 | causes auditd to dump a report of internal state to /var/run/auditd.state. |
54 | ||
55 | .SH EXIT CODES | |
56 | .TP | |
57 | .B 1 | |
58 | Cannot adjust priority, daemonize, open audit netlink, write the pid file, start up plugins, resolve the machine name, set audit pid, or other initialization tasks. | |
59 | ||
60 | .TP | |
61 | .B 2 | |
62 | Invalid or excessive command line arguments | |
63 | ||
64 | .TP | |
65 | .B 4 | |
66 | The audit daemon doesn't have sufficient privilege | |
67 | ||
68 | .TP | |
69 | .B 6 | |
70 | There is an error in the configuration file | |
54 | 71 | |
55 | 72 | .SH FILES |
56 | 73 | .B /etc/audit/auditd.conf |
26 | 26 | # By default we don't clear the rules on exit. To enable this, uncomment |
27 | 27 | # the next line after copying the file to /etc/systemd/system/auditd.service |
28 | 28 | #ExecStopPost=/sbin/auditctl -R /etc/audit/audit-stop.rules |
29 | Restart=on-failure | |
30 | # Do not restart for intentional exits. See EXIT CODES section in auditd(8). | |
31 | RestartPreventExitStatus=2 4 6 | |
29 | 32 | |
30 | 33 | ### Security Settings ### |
31 | 34 | MemoryDenyWriteExecute=true |
558 | 558 | |
559 | 559 | int audit_set_feature(int fd, unsigned feature, unsigned value, unsigned lock) |
560 | 560 | { |
561 | #if defined(HAVE_DECL_AUDIT_FEATURE_VERSION) | |
561 | #if HAVE_DECL_AUDIT_FEATURE_VERSION == 1 | |
562 | 562 | int rc; |
563 | 563 | struct audit_features f; |
564 | 564 | |
582 | 582 | |
583 | 583 | int audit_request_features(int fd) |
584 | 584 | { |
585 | #if defined(HAVE_DECL_AUDIT_FEATURE_VERSION) | |
585 | #if HAVE_DECL_AUDIT_FEATURE_VERSION == 1 | |
586 | 586 | int rc; |
587 | 587 | struct audit_features f; |
588 | 588 | |
601 | 601 | |
602 | 602 | extern int audit_set_loginuid_immutable(int fd) |
603 | 603 | { |
604 | #if defined(HAVE_DECL_AUDIT_FEATURE_VERSION) | |
604 | #if HAVE_DECL_AUDIT_FEATURE_VERSION == 1 | |
605 | 605 | return audit_set_feature(fd, AUDIT_FEATURE_LOGINUID_IMMUTABLE, 1, 1); |
606 | 606 | #else |
607 | 607 | errno = EINVAL; |
39 | 39 | #endif |
40 | 40 | #ifdef WITH_AARCH64 |
41 | 41 | _S(MACH_AARCH64, "aarch64" ) |
42 | _S(MACH_AARCH64, "armv8l") | |
42 | 43 | #endif |
146 | 146 | rep->error = NULL; |
147 | 147 | rep->signal_info = NULL; |
148 | 148 | rep->conf = NULL; |
149 | #if defined(HAVE_DECL_AUDIT_FEATURE_VERSION) | |
149 | #if HAVE_DECL_AUDIT_FEATURE_VERSION == 1 | |
150 | 150 | rep->features = NULL; |
151 | 151 | #endif |
152 | 152 | if (!NLMSG_OK(rep->nlh, (unsigned int)len)) { |
171 | 171 | case AUDIT_GET: |
172 | 172 | rep->status = NLMSG_DATA(rep->nlh); |
173 | 173 | break; |
174 | #if defined(HAVE_DECL_AUDIT_FEATURE_VERSION) | |
174 | #if HAVE_DECL_AUDIT_FEATURE_VERSION == 1 | |
175 | 175 | case AUDIT_GET_FEATURE: |
176 | 176 | rep->features = NLMSG_DATA(rep->nlh); |
177 | 177 | break; |
584 | 584 | #endif |
585 | 585 | printed = 1; |
586 | 586 | break; |
587 | #if defined(HAVE_DECL_AUDIT_FEATURE_VERSION) | |
587 | #if HAVE_DECL_AUDIT_FEATURE_VERSION == 1 | |
588 | 588 | case AUDIT_GET_FEATURE: |
589 | 589 | { |
590 | 590 | uint32_t mask = AUDIT_FEATURE_TO_MASK( |
134 | 134 | " -v Version\n" |
135 | 135 | " -w <path> Insert watch at <path>\n" |
136 | 136 | " -W <path> Remove watch at <path>\n" |
137 | #if defined(HAVE_DECL_AUDIT_FEATURE_VERSION) | |
137 | #if HAVE_DECL_AUDIT_FEATURE_VERSION == 1 | |
138 | 138 | " --loginuid-immutable Make loginuids unchangeable once set\n" |
139 | 139 | #endif |
140 | 140 | #if HAVE_DECL_AUDIT_VERSION_BACKLOG_WAIT_TIME == 1 || \ |
367 | 367 | return 0; |
368 | 368 | } |
369 | 369 | |
370 | static void check_rule_mismatch(int lineno, const char *option) | |
370 | static int check_rule_mismatch(int lineno, const char *option) | |
371 | 371 | { |
372 | 372 | struct audit_rule_data tmprule; |
373 | 373 | unsigned int old_audit_elf = _audit_elf; |
385 | 385 | _audit_elf = AUDIT_ARCH_S390; |
386 | 386 | break; |
387 | 387 | } |
388 | ||
389 | char *ptr, *saved, *tmp = strdup(option); | |
390 | if (tmp == NULL) | |
391 | return -1; | |
392 | ptr = strtok_r(tmp, ",", &saved); | |
388 | 393 | memset(&tmprule, 0, sizeof(struct audit_rule_data)); |
389 | audit_rule_syscallbyname_data(&tmprule, option); | |
394 | while (ptr) { | |
395 | audit_rule_syscallbyname_data(&tmprule, ptr); | |
396 | ptr = strtok_r(NULL, ",", &saved); | |
397 | } | |
390 | 398 | if (memcmp(tmprule.mask, rule_new->mask, AUDIT_BITMASK_SIZE)) |
391 | 399 | rc = 1; |
400 | free(tmp); | |
401 | ||
392 | 402 | _audit_elf = old_audit_elf; |
393 | if (rc) { | |
403 | if (rc) { | |
394 | 404 | if (lineno) |
395 | 405 | audit_msg(LOG_WARNING, "WARNING - 32/64 bit syscall mismatch in line %d, you should specify an arch", lineno); |
396 | 406 | else |
397 | 407 | audit_msg(LOG_WARNING, "WARNING - 32/64 bit syscall mismatch, you should specify an arch"); |
398 | 408 | } |
409 | return 0; | |
399 | 410 | } |
400 | 411 | |
401 | 412 | |
531 | 542 | |
532 | 543 | static struct option long_opts[] = |
533 | 544 | { |
534 | #if defined(HAVE_DECL_AUDIT_FEATURE_VERSION) | |
545 | #if HAVE_DECL_AUDIT_FEATURE_VERSION == 1 | |
535 | 546 | {"loginuid-immutable", 0, NULL, 1}, |
536 | 547 | #endif |
537 | 548 | #if HAVE_DECL_AUDIT_VERSION_BACKLOG_WAIT_TIME == 1 || \ |
823 | 834 | case 0: |
824 | 835 | _audit_syscalladded = 1; |
825 | 836 | if (unknown_arch && add != AUDIT_FILTER_UNSET) |
826 | check_rule_mismatch(lineno, optarg); | |
837 | if (check_rule_mismatch(lineno, optarg) == -1) | |
838 | retval = -1; | |
827 | 839 | break; |
828 | 840 | case -1: |
829 | 841 | audit_msg(LOG_ERR, "Syscall name unknown: %s", |
191 | 191 | if (f == NULL) |
192 | 192 | return; |
193 | 193 | |
194 | fprintf(f, "audit version = %s\n", VERSION); | |
194 | 195 | time_t now = time(0); |
195 | 196 | strftime(buf, sizeof(buf), "%x %X", localtime(&now)); |
196 | 197 | fprintf(f, "current time = %s\n", buf); |
193 | 193 | // Now should be pointing to msg= |
194 | 194 | ptr = audit_strsplit(NULL); |
195 | 195 | // strlen is for fuzzers that make invalid lines |
196 | if (ptr && strlen(ptr) > 24) { | |
196 | if (ptr && strnlen(ptr, 20) > 18) { | |
197 | 197 | if (*(ptr+9) == '(') |
198 | 198 | ptr+=9; |
199 | 199 | else |
95 | 95 | int mins, hours, days; |
96 | 96 | if (notime) |
97 | 97 | printf("- %-7.5s", " "); |
98 | else | |
99 | printf("- %-7.5s", ctime(&cur->end) + 11); | |
98 | else { | |
99 | char *ttime = ctime(&cur->end); | |
100 | printf("- %-7.5s", ttime ? ttime + 11 : | |
101 | "bad value"); | |
102 | } | |
100 | 103 | secs = cur->end - cur->start; |
101 | 104 | mins = (secs / 60) % 60; |
102 | 105 | hours = (secs / 3600) % 24; |
127 | 130 | strftime(start, sizeof(start), "%x %T", btm); |
128 | 131 | if (cur->end != 0) { |
129 | 132 | btm = localtime(&cur->end); |
130 | strftime(end, sizeof(end), "%x %T", btm); | |
131 | printf(" ausearch --start %s --end %s", | |
132 | start, end); | |
133 | if (btm) { | |
134 | strftime(end, sizeof(end), "%x %T", btm); | |
135 | printf(" ausearch --start %s --end %s", | |
136 | start, end); | |
137 | } else goto no_end; | |
133 | 138 | } else { |
139 | no_end: | |
134 | 140 | printf(" ausearch --start %s", start); |
135 | 141 | } |
136 | 142 | if (cur->name == NULL) |
3 | 3 | .SH SYNOPSIS |
4 | 4 | .B ausyscall [arch] name | number | \-\-dump | \-\-exact |
5 | 5 | .SH DESCRIPTION |
6 | \fBausyscall\fP is a program that prints out the mapping from syscall name to number and reverse for the given arch. The arch can be anything returned by `uname \-m`. If arch is not given, the program will take a guess based on the running image. You may give the syscall name or number and it will find the opposite. You can also dump the whole table with the \-\-dump option. By default a syscall name lookup will be a substring match meaning that it will try to match all occurrences of the given name with syscalls. So giving a name of chown will match both fchown and chown as any other syscall with chown in its name. If this behavior is not desired, pass the \-\-exact flag and it will do an exact string match. | |
6 | \fBausyscall\fP is a program that prints out the mapping from syscall name to number and reverse for the given arch. The arch can be anything returned by `uname \-m`. If arch is not given, the program will take a guess based on the running image. Or for convenience, you can pass \fBb32\fP or \fBb64\fP to use the current arch but a specific ABI. You may give the syscall name or number and it will find the opposite. You can also dump the whole table with the \-\-dump option. By default a syscall name lookup will be a substring match meaning that it will try to match all occurrences of the given name with syscalls. So giving a name of chown will match both fchown and chown as any other syscall with chown in its name. If this behavior is not desired, pass the \-\-exact flag and it will do an exact string match. | |
7 | 7 | |
8 | 8 | This program can be used to verify syscall numbers on a biarch platform for rule optimization. For example, suppose you had an auditctl rule: |
9 | 9 | |
10 | 10 | .B \-a always, exit \-S open \-F exit=\-EPERM \-k fail\-open |
11 | 11 | |
12 | If you wanted to verify that both 32 and 64 bit programs would be audited, run "ausyscall i386 open" and then "ausyscall x86_64 open". Look at the returned numbers. If they are different, you will have to write two auditctl rules to get complete coverage. | |
12 | If you wanted to verify that both 32 and 64 bit programs would be audited, run "ausyscall i386 open" and then "ausyscall x86_64 open". (Or use the b32 and b64 option.) Look at the returned numbers. If they are different, you will have to write two auditctl rules to get complete coverage. | |
13 | 13 | |
14 | 14 | .nf |
15 | 15 | .B \-a always,exit \-F arch=b32 \-S open \-F exit=\-EPERM \-k fail\-open |