diff --git a/TTY-hostname.patch b/TTY-hostname.patch new file mode 100644 index 0000000000000000000000000000000000000000..c5a78c56f07d7bf0151b8d4cf4145f460e484f1c --- /dev/null +++ b/TTY-hostname.patch @@ -0,0 +1,14 @@ +diff --git a/lib/audit_logging.c b/lib/audit_logging.c +index 4da95b5e6..f63c37d2c 100644 +--- a/lib/audit_logging.c ++++ b/lib/audit_logging.c +@@ -243,7 +243,8 @@ static const char *_get_hostname(const char *ttyn) + { + if (ttyn && ((strncmp(ttyn, "pts", 3) == 0) || + (strncmp(ttyn, "tty", 3) == 0) || +- (strncmp(ttyn, "/dev/tty", 8) == 0) )) { ++ (strncmp(ttyn, "/dev/tty", 8) == 0) || ++ (strncmp(ttyn, "/dev/pts", 8) == 0) )) { + if (_host[0] == 0) { + gethostname(_host, HOSTLEN); + _host[HOSTLEN - 1] = 0; diff --git a/audit-3.1.2.tar.gz b/audit-3.1.2.tar.gz deleted file mode 100644 index cef95796292e20e2e3cd3bdf453519a7ed4c8eb5..0000000000000000000000000000000000000000 Binary files a/audit-3.1.2.tar.gz and /dev/null differ diff --git a/audit-4.0.3.tar.gz b/audit-4.0.3.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..e72a568ba8722f584697ecad9d78714eaa2dbc73 Binary files /dev/null and b/audit-4.0.3.tar.gz differ diff --git a/audit.spec b/audit.spec index 407311796761e209575dd2e268b5d281e0858856..c8cf9a20a7e4705b73bde105ce056adec9a3e3c1 100644 --- a/audit.spec +++ b/audit.spec @@ -1,8 +1,8 @@ -%define anolis_release 4 +%define anolis_release 1 Summary: User space tools for kernel auditing Name: audit -Version: 3.1.2 +Version: 4.0.3 Release: %{anolis_release}%{?dist} License: GPL-2.0-or-later AND LGPL-2.0-or-later URL: https://github.com/linux-audit/audit-userspace/ @@ -10,6 +10,14 @@ Source0: https://github.com/linux-audit/audit-userspace/archive/v%{version}/%{na Source1: https://www.gnu.org/licenses/lgpl-2.1.txt Patch0: 0001-Add-loongarch-support-for-audit-userspace.patch +Patch1: TTY-hostname.patch +Patch2: permtab-unsupport-syscalls-v2.patch +Patch3: ausearch-checkpoint-race.patch +Patch4: permtab-unsupport-syscalls-v1.patch +Patch5: timebased-log-rotation.patch +Patch6: remove-HALT-spaceleftaction.patch +Patch7: warning-before-HALT.patch +Patch8: remote-logging-ordering-cycle.patch BuildRequires: make gcc BuildRequires: krb5-devel @@ -282,6 +290,10 @@ fi %doc README ChangeLog %changelog +* Fri Jun 27 2025 wenyuzifang - 4.0.3-1 +- Updated to version 4.0.3 to fix xxxxxxxxx +- Ensure reliable checkpointing by evaluating it early, preventing missed starting points and empty outputs. + * Tue Jun 17 2025 mgb01105731 - 3.1.2-4 - Upstream url changed @@ -320,4 +332,4 @@ fi - Apply flex array workaround from upstream * Fri Mar 11 2022 Caspar Zhang 3.0.7-1 -- New upstream release for Anolis OS 23 +- New upstream release for Anolis OS 23 \ No newline at end of file diff --git a/ausearch-checkpoint-race.patch b/ausearch-checkpoint-race.patch new file mode 100644 index 0000000000000000000000000000000000000000..ce3e30a83e62589d907977064b878a5036bfa1ef --- /dev/null +++ b/ausearch-checkpoint-race.patch @@ -0,0 +1,35 @@ +diff --git a/src/ausearch.c b/src/ausearch.c +index 3bf95b5a..cf77ba14 100644 +--- a/src/ausearch.c ++++ b/src/ausearch.c +@@ -464,6 +464,17 @@ static int process_log_fd(void) + if ((ret != 0)||(entries->cnt == 0)) + break; + ++ /* ++ * If we are checkpointing, decide if we output this event. ++ * We need to do it as early as here. The chkpt_input_levent event ++ * might not match the entries, so we need to ensure that we don't ++ * skip the event that is the checkpoint event. That is the marking point ++ * from which we start outputting events. Leaving that event out will produce ++ * empty results. ++ */ ++ if (checkpt_filename) ++ do_output = chkpt_output_decision(&entries->e); ++ + /* + * We flush all events on the last log file being processed. + * Thus incomplete events are 'carried forward' to be +@@ -471,12 +482,6 @@ static int process_log_fd(void) + * in the next file we are about to process. + */ + if (match(entries)) { +- /* +- * If we are checkpointing, decide if we output +- * this event +- */ +- if (checkpt_filename) +- do_output = chkpt_output_decision(&entries->e); + + if (do_output == 1) { + found = 1; diff --git a/permtab-unsupport-syscalls-v1.patch b/permtab-unsupport-syscalls-v1.patch new file mode 100644 index 0000000000000000000000000000000000000000..5c11a3c003a550234c6855636526c68bd334f2aa --- /dev/null +++ b/permtab-unsupport-syscalls-v1.patch @@ -0,0 +1,102 @@ +diff --git a/lib/libaudit.c b/lib/libaudit.c +index 7a8c6d4b1..de34812f0 100644 +--- a/lib/libaudit.c ++++ b/lib/libaudit.c +@@ -100,6 +100,7 @@ static struct libaudit_conf config; + static int audit_failure_parser(const char *val, int line); + static int audit_name_to_uid(const char *name, uid_t *auid); + static int audit_name_to_gid(const char *name, gid_t *gid); ++static char* filter_supported_syscalls(const char* syscalls, int machine) __attr_dealloc_free; + + static const struct kw_pair keywords[] = + { +@@ -1524,6 +1525,50 @@ int _audit_parse_syscall(const char *optarg, struct audit_rule_data *rule) + return audit_rule_syscallbyname_data(rule, optarg); + } + ++/* ++ * Filters unsupported syscalls from a comma-separated string based ++ * on the given architecture. Returns a new string with supported syscalls ++ * or NULL on error. ++ */ ++static char* filter_supported_syscalls(const char* syscalls, int machine) ++{ ++ if (syscalls == NULL) { ++ return NULL; ++ } ++ ++ // Allocate memory for the filtered syscalls string ++ char* filtered_syscalls = malloc(strlen(syscalls) + 1); ++ if (filtered_syscalls == NULL) { ++ return NULL; ++ } ++ filtered_syscalls[0] = '\0'; // Initialize as empty string ++ ++ // Tokenize the syscalls string and filter unsupported syscalls ++ const char* delimiter = ","; ++ char* syscalls_copy = strdup(syscalls); ++ if (syscalls_copy == NULL) { ++ free(filtered_syscalls); ++ return NULL; ++ } ++ char* token = strtok(syscalls_copy, delimiter); ++ while (token != NULL) { ++ if (audit_name_to_syscall(token, machine) != -1) { ++ strcat(filtered_syscalls, token); ++ strcat(filtered_syscalls, delimiter); ++ } ++ token = strtok(NULL, delimiter); ++ } ++ free(syscalls_copy); ++ ++ // Remove the trailing delimiter, if present ++ size_t len = strlen(filtered_syscalls); ++ if (len > 0 && filtered_syscalls[len - 1] == ',') { ++ filtered_syscalls[len - 1] = '\0'; ++ } ++ ++ return filtered_syscalls; ++} ++ + static int audit_add_perm_syscalls(int perm, struct audit_rule_data *rule) + { + // We only get here if syscall notation is being used in the rule. +@@ -1536,20 +1581,36 @@ static int audit_add_perm_syscalls(int perm, struct audit_rule_data *rule) + return 0; + } + ++ const int machine = audit_elf_to_machine(_audit_elf); + const char *syscalls = audit_perm_to_name(perm); +- int rc = _audit_parse_syscall(syscalls, rule); ++ const char *syscalls_to_use; ++ ++ // The permtab table is hardcoded, but some syscalls, like rename ++ // on arm64, are unavailable on certain architectures. To ensure compatibility, ++ // we must avoid creating rules with unsupported syscalls. ++ char* filtered_syscalls = filter_supported_syscalls(syscalls, machine); ++ if (filtered_syscalls == NULL) { ++ // use original syscalls in case we failed to parse - should not happen ++ syscalls_to_use = syscalls; ++ audit_msg(LOG_WARNING, "Filtering syscalls failed; using original syscalls."); ++ } else { ++ syscalls_to_use = filtered_syscalls; ++ } ++ ++ int rc = _audit_parse_syscall(syscalls_to_use, rule); + switch (rc) + { + case 0: + _audit_syscalladded = 1; + break; + case -1: // Should never happen +- audit_msg(LOG_ERR, "Syscall name unknown: %s", syscalls); ++ audit_msg(LOG_ERR, "Syscall name unknown: %s", syscalls_to_use); + break; + default: // Error reported - do nothing here + break; + } + ++ free(filtered_syscalls); + return rc; + } + diff --git a/permtab-unsupport-syscalls-v2.patch b/permtab-unsupport-syscalls-v2.patch new file mode 100644 index 0000000000000000000000000000000000000000..7557f3f29e6397d9a688d12555bca6adee059850 --- /dev/null +++ b/permtab-unsupport-syscalls-v2.patch @@ -0,0 +1,58 @@ +diff --git a/lib/libaudit.c b/lib/libaudit.c +index de34812f0..61f9bd9da 100644 +--- a/lib/libaudit.c ++++ b/lib/libaudit.c +@@ -1536,37 +1536,35 @@ static char* filter_supported_syscalls(const char* syscalls, int machine) + return NULL; + } + +- // Allocate memory for the filtered syscalls string +- char* filtered_syscalls = malloc(strlen(syscalls) + 1); +- if (filtered_syscalls == NULL) { +- return NULL; +- } +- filtered_syscalls[0] = '\0'; // Initialize as empty string +- +- // Tokenize the syscalls string and filter unsupported syscalls ++ char buf[512] = ""; ++ char* ptr = buf; + const char* delimiter = ","; ++ + char* syscalls_copy = strdup(syscalls); +- if (syscalls_copy == NULL) { +- free(filtered_syscalls); ++ if (syscalls_copy == NULL) + return NULL; +- } ++ + char* token = strtok(syscalls_copy, delimiter); ++ int first = 1; // Track if this is the first syscall being added ++ + while (token != NULL) { + if (audit_name_to_syscall(token, machine) != -1) { +- strcat(filtered_syscalls, token); +- strcat(filtered_syscalls, delimiter); ++ if (!first) ++ *ptr++ = ','; ++ ptr = stpcpy(ptr, token); ++ first = 0; + } + token = strtok(NULL, delimiter); + } ++ + free(syscalls_copy); + +- // Remove the trailing delimiter, if present +- size_t len = strlen(filtered_syscalls); +- if (len > 0 && filtered_syscalls[len - 1] == ',') { +- filtered_syscalls[len - 1] = '\0'; ++ // If no valid syscalls were found, return NULL ++ if (ptr == buf) { ++ return NULL; + } + +- return filtered_syscalls; ++ return strdup(buf); + } + + static int audit_add_perm_syscalls(int perm, struct audit_rule_data *rule) diff --git a/remote-logging-ordering-cycle.patch b/remote-logging-ordering-cycle.patch new file mode 100644 index 0000000000000000000000000000000000000000..cc30a0df3bd57ae46ba23f9babafaa0c292bbbe9 --- /dev/null +++ b/remote-logging-ordering-cycle.patch @@ -0,0 +1,14 @@ +diff --git a/init.d/auditd.service.in b/init.d/auditd.service.in +index 173795164..853912f61 100644 +--- a/init.d/auditd.service.in ++++ b/init.d/auditd.service.in +@@ -16,6 +16,9 @@ Wants=audit-rules.service + ## a minimal file that overrides only the necessary lines but inherits the + ## original settings in case they get updated by a distribution. Please check + ## systemd documentation if it's unclear how to override settings. ++## If using remote logging, ensure that the systemd-update-utmp.service file ++## is updated to remove the After=auditd.service directive to prevent a ++## boot-time ordering cycle. + After=local-fs.target systemd-tmpfiles-setup.service + #After=network-online.target local-fs.target systemd-tmpfiles-setup.service + Before=sysinit.target shutdown.target audit-rules.service diff --git a/remove-HALT-spaceleftaction.patch b/remove-HALT-spaceleftaction.patch new file mode 100644 index 0000000000000000000000000000000000000000..29ff7f1bfcc855ffc32691f9d9b83e087c1d607d --- /dev/null +++ b/remove-HALT-spaceleftaction.patch @@ -0,0 +1,164 @@ +diff --git a/docs/auditd.conf.5 b/docs/auditd.conf.5 +index 0b785e7a3..fae6efda9 100644 +--- a/docs/auditd.conf.5 ++++ b/docs/auditd.conf.5 +@@ -156,7 +156,7 @@ while the audit daemon is running, you should send the audit daemon SIGHUP to re + This parameter tells the system what action to take when the system has + detected that it is starting to get low on disk space. + Valid values are +-.IR ignore ", " syslog ", " rotate ", " email ", " exec ", " suspend ", " single ", and " halt . ++.IR ignore ", " syslog ", " rotate ", " email ", " exec ", " suspend ", and " single . + If set to + .IR ignore , + the audit daemon does nothing. +@@ -173,9 +173,20 @@ as well as sending the message to syslog. + .I suspend + will cause the audit daemon to stop writing records to the disk. The daemon will still be alive. The + .I single +-option will cause the audit daemon to put the computer system in single user mode. The ++option will cause the audit daemon to put the computer system in single user mode. Except for rotate, it will perform this action just one time. The previously available + .I halt +-option will cause the audit daemon to shutdown the computer system. Except for rotate, it will perform this action just one time. ++option, which would cause the audit daemon to shut down the computer system, has been deprecated and should no longer be used. It was determined that halting the system at this stage could lead to unintended consequences and is considered a bad action if selected. ++ ++Disk space notifications follow a three-stage progression. The ++.I space_left_action ++is the low water mark and serves as the first warning that disk space is running low. Halting at this stage is not recommended, as it prevents administrators from taking corrective action. The next stage, ++.I admin_space_left_action, ++indicates an emergency level where immediate action is required to free up disk space. Administrators should configure critical responses for this level. Finally, the ++.I disk_full_action ++occurs when the disk is completely full. At this stage, the system may have already halted, and preemptive measures configured in earlier stages will determine the system’s behavior. ++ ++ ++ + .TP + .I admin_space_left + This is a numeric value in megabytes that tells the audit daemon when +diff --git a/src/auditd-config.c b/src/auditd-config.c +index b2992e647..5065e6aa6 100644 +--- a/src/auditd-config.c ++++ b/src/auditd-config.c +@@ -1034,6 +1034,11 @@ static int space_action_parser(const struct nv_pair *nv, int line, + if (check_exe_name(nv->option, line)) + return 1; + config->space_left_exe = strdup(nv->option); ++ } else if (failure_actions[i].option == FA_HALT) { ++ audit_msg(LOG_ERR, ++ "The HALT option in space_left_action has been deprecated" ++ " to prevent system instability from premature shutdowns."); ++ return 1; + } + config->space_left_action = failure_actions[i].option; + return 0; +@@ -1043,6 +1048,13 @@ static int space_action_parser(const struct nv_pair *nv, int line, + return 1; + } + ++const char *failure_action_to_str(unsigned int action) ++{ ++ if (action > FA_HALT) ++ return "unknown"; ++ return failure_actions[action].name; ++} ++ + // returns 0 if OK, 1 on temp error, 2 on permanent error + static int validate_email(const char *acct) + { +diff --git a/src/auditd-config.h b/src/auditd-config.h +index dae6a5086..3d7170476 100644 +--- a/src/auditd-config.h ++++ b/src/auditd-config.h +@@ -114,4 +114,6 @@ int start_config_manager(struct auditd_event *e); + #endif + void free_config(struct daemon_conf *config); + ++const char *failure_action_to_str(unsigned int action); ++ + #endif +diff --git a/src/auditd-event.c b/src/auditd-event.c +index fb3b98be4..3a64d5aae 100644 +--- a/src/auditd-event.c ++++ b/src/auditd-event.c +@@ -829,19 +829,36 @@ extern int sendmail(const char *subject, const char *content, + static void do_space_left_action(int admin) + { + int action; ++ char buffer[256]; ++ const char *next_actions; + +- if (admin) ++ // Select the appropriate action and generate a meaningful message ++ // explaining what happens if disk space reaches a threshold or ++ // becomes completely full. ++ if (admin) { + action = config->admin_space_left_action; +- else ++ ++ snprintf(buffer, sizeof(buffer), ++ "If the disk becomes full, audit will %s.", failure_action_to_str(config->disk_full_action)); ++ } ++ else { + action = config->space_left_action; + ++ snprintf(buffer, sizeof(buffer), ++ "If the admin space left threshold is reached, audit will %s. " ++ "If the disk becomes full, audit will %s.", ++ failure_action_to_str(config->admin_space_left_action), ++ failure_action_to_str(config->disk_full_action)); ++ } ++ next_actions = buffer; ++ + switch (action) + { + case FA_IGNORE: + break; + case FA_SYSLOG: + audit_msg(LOG_ALERT, +- "Audit daemon is low on disk space for logging"); ++ "Audit daemon is low on disk space for logging. %s", next_actions); + break; + case FA_ROTATE: + if (config->num_logs > 1) { +@@ -851,19 +868,24 @@ static void do_space_left_action(int admin) + } + break; + case FA_EMAIL: ++ char content[512]; ++ const char *subject; ++ + if (admin == 0) { +- sendmail("Audit Disk Space Alert", +- "The audit daemon is low on disk space for logging! Please take action\nto ensure no loss of service.", +- config->action_mail_acct); +- audit_msg(LOG_ALERT, +- "Audit daemon is low on disk space for logging"); ++ subject = "Audit Disk Space Alert"; ++ snprintf(content, sizeof(content), ++ "The audit daemon is low on disk space for logging! Please take action\n" ++ "to ensure no loss of service.\n" ++ "%s", next_actions); + } else { +- sendmail("Audit Admin Space Alert", +- "The audit daemon is very low on disk space for logging! Immediate action\nis required to ensure no loss of service.", +- config->action_mail_acct); +- audit_msg(LOG_ALERT, +- "Audit daemon is very low on disk space for logging"); ++ subject = "Audit Admin Space Alert"; ++ snprintf(content, sizeof(content), ++ "The audit daemon is very low on disk space for logging! Immediate action\n" ++ "is required to ensure no loss of service.\n" ++ "%s", next_actions); + } ++ sendmail(subject, content, config->action_mail_acct); ++ audit_msg(LOG_ALERT, "%s", content); + break; + case FA_EXEC: + // Close the logging file in case the script zips or +@@ -897,6 +919,7 @@ static void do_space_left_action(int admin) + stop = 1; + break; + case FA_HALT: ++ // Only available for admin + audit_msg(LOG_ALERT, + "The audit daemon is now halting the system and exiting due to low disk space"); + change_runlevel(HALT); diff --git a/timebased-log-rotation.patch b/timebased-log-rotation.patch new file mode 100644 index 0000000000000000000000000000000000000000..3f9002d394fd58794f474608675f845a5f546f6a --- /dev/null +++ b/timebased-log-rotation.patch @@ -0,0 +1,134 @@ +diff --git a/audit.spec b/audit.spec +index ee839006a..5ca742888 100644 +--- a/audit.spec ++++ b/audit.spec +@@ -210,6 +210,7 @@ fi + %attr(644,root,root) %{_mandir}/man8/aulastlog.8.gz + %attr(644,root,root) %{_mandir}/man8/ausyscall.8.gz + %attr(644,root,root) %{_mandir}/man5/auditd.conf.5.gz ++%attr(644,root,root) %{_mandir}/man5/auditd.cron.5.gz + %attr(644,root,root) %{_mandir}/man5/auditd-plugins.5.gz + %attr(755,root,root) %{_sbindir}/auditd + %attr(755,root,root) %{_sbindir}/ausearch +diff --git a/docs/Makefile.am b/docs/Makefile.am +index 9db23cb3d..410ecda62 100644 +--- a/docs/Makefile.am ++++ b/docs/Makefile.am +@@ -68,5 +68,6 @@ ausearch_next_event.3 ausearch_cur_event.3 ausearch_set_stop.3 \ + get_auditfail_action.3 set_aumessage_mode.3 \ + audispd-zos-remote.8 libaudit.conf.5 \ + augenrules.8 audit_set_backlog_wait_time.3 \ +-zos-remote.conf.5 ++zos-remote.conf.5 \ ++auditd.cron.5 + +diff --git a/docs/auditd.conf.5 b/docs/auditd.conf.5 +index fae6efda9..d5765dd43 100644 +--- a/docs/auditd.conf.5 ++++ b/docs/auditd.conf.5 +@@ -432,6 +432,10 @@ record type >= AUDIT_MAC_UNLBL_ALLOW && record type <= AUDIT_MAC_CALIPSO_DEL (th + for the stream being processed, the time of the event is over end_of_event_timeout seconds old. + .RE + ++.SH LOG ROTATION POLICY ++ ++By default, auditd uses size-based log rotation. If you prefer time-based rotation (e.g., hourly, daily, weekly, or custom schedule), refer to auditd.cron(5) for configuration details. ++ + .SH FILES + .TP + .I /etc/audit/auditd.conf +@@ -440,7 +444,8 @@ Audit daemon configuration file + .SH "SEE ALSO" + .BR auditd (8), + .BR audisp\-remote.conf (5), +-.BR auditd\-plugins (5). ++.BR auditd\-plugins (5), ++.BR auditd.cron (5). + + .SH AUTHOR + Steve Grubb +diff --git a/docs/auditd.cron.5 b/docs/auditd.cron.5 +new file mode 100644 +index 000000000..af1409823 +--- /dev/null ++++ b/docs/auditd.cron.5 +@@ -0,0 +1,66 @@ ++.TH AUDITD.CRON "5" "Feb 2025" "Red Hat" "System Administration Utilities" ++.SH NAME ++auditd.conf \- time-based rotation of audit logs ++.SH DESCRIPTION ++By default, the audit daemon (auditd) supports size-based log rotation, where logs are rotated once they reach a specified size, as configured in ++.I /etc/audit/auditd.conf. ++This manual describes an alternative method: time-based log rotation using ++.B cron. ++Using this approach, audit logs can be rotated at specified intervals (hourly, daily, weekly or on a custom date), regardless of their size. ++ ++.SH CONFIGURATION ++ ++.B 1.Disable Size-Based Rotation: ++ ++To enable time-based log rotation, first disable \fBauditd's\fP built-in size-based rotation by setting the following parameter in ++.I /etc/audit/auditd.conf: ++ ++.RS ++max_log_file_action = ignore ++.RE ++ ++.B 2. Configure Log Retention: ++ ++The ++.B num_logs ++parameter determines the number of rotated log files to keep. For daily rotation, setting ++ ++.RS ++num_logs = 7 ++.RE ++ ++ensures that logs from the last seven days are retained. However, on busy systems, audit logs may grow rapidly, potentially leading to a lack of disk space. To prevent this, ensure that the ++.B space_left_action ++parameter is configured to handle low-disk-space situations appropriately. ++ ++.B 3. Apply Configuration Changes: ++ ++After modifying the main auditd configuration file, reload auditd to apply the changes: ++ ++.RS ++auditctl --signal reload ++.RE ++ ++.B 4. Deploy the Rotation Script: ++ ++Copy the provided ++.B auditd.cron ++script to the appropriate cron directory ( ++.IR cron.daily ++or ++.IR cron.hourly ++or ++.IR cron.weekly ++, depending on your rotation preference). Then, ensure the file has the correct SELinux labels: ++ ++.RS ++cp /usr/share/doc/audit/auditd.cron /etc/cron.daily ++.RE ++ ++.SH "SEE ALSO" ++.BR auditd.conf (5), ++.BR auditd (8), ++.BR cron(8). ++ ++.SH AUTHOR ++Attila Lakatos +diff --git a/init.d/auditd.cron b/init.d/auditd.cron +index 825cb227d..e692231df 100644 +--- a/init.d/auditd.cron ++++ b/init.d/auditd.cron +@@ -5,7 +5,7 @@ + # based on time instead of log size. + ########## + +-/sbin/auditctl --signal usr1 ++/sbin/auditctl --signal rotate + EXITVALUE=$? + if [ $EXITVALUE != 0 ]; then + /usr/bin/logger -t auditd "ALERT auditctl exited abnormally with [$EXITVALUE] while rotating the logs" diff --git a/warning-before-HALT.patch b/warning-before-HALT.patch new file mode 100644 index 0000000000000000000000000000000000000000..61d4d8a29bf2d0ae6130e8395c6518ff2de0bfd7 --- /dev/null +++ b/warning-before-HALT.patch @@ -0,0 +1,87 @@ +diff --git a/common/common.c b/common/common.c +index cd15b1691..13065a0c7 100644 +--- a/common/common.c ++++ b/common/common.c +@@ -25,6 +25,8 @@ + #include + #include + #include ++#include ++#include + + /* + * This function returns 1 if it is the last record in an event. +@@ -75,4 +77,36 @@ int write_to_console(const char *fmt, ...) + close(fd); + + return res; ++} ++ ++void wall_message(const char* format, ...) ++{ ++ struct utmpx* entry; ++ char message[512]; ++ va_list args; ++ int fd; ++ ++ // Format the message ++ va_start(args, format); ++ vsnprintf(message, sizeof(message), format, args); ++ va_end(args); ++ ++ setutxent(); ++ ++ // Send the message to all active users ++ while ((entry = getutxent())) { ++ // Only active users have a valid terminal ++ if (entry->ut_type == USER_PROCESS) { ++ char tty_path[128]; ++ snprintf(tty_path, sizeof(tty_path), "/dev/%s", entry->ut_line); ++ ++ fd = open(tty_path, O_WRONLY | O_NOCTTY); ++ if (fd != -1) { ++ dprintf(fd, "\nBroadcast message from audit daemon:\n%s\n", message); ++ close(fd); ++ } ++ } ++ } ++ ++ endutxent(); + } +\ No newline at end of file +diff --git a/common/common.h b/common/common.h +index 5d4b66945..61dbe7d23 100644 +--- a/common/common.h ++++ b/common/common.h +@@ -57,6 +57,13 @@ int write_to_console(const char *fmt, ...) + ; + #endif + ++void wall_message(const char *fmt, ...) ++#ifdef __GNUC__ ++ __attribute__((format(printf, 1, 2))); ++#else ++ ; ++#endif ++ + AUDIT_HIDDEN_END + #endif + +diff --git a/src/auditd-event.c b/src/auditd-event.c +index 3a64d5aae..a6eeb2c18 100644 +--- a/src/auditd-event.c ++++ b/src/auditd-event.c +@@ -852,6 +852,13 @@ static void do_space_left_action(int admin) + } + next_actions = buffer; + ++ // If space_left is reached and FA_HALT is set in any of these fields ++ // we need to inform logged in users. ++ if (config->admin_space_left_action == FA_HALT || ++ config->disk_full_action == FA_HALT) { ++ wall_message("The audit system is low on disk space and is now halting the system for admin corrective action."); ++ } ++ + switch (action) + { + case FA_IGNORE: