]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
journal: make JournalConfig.set_audit as enum 39069/head
authorYu Watanabe <watanabe.yu+github@gmail.com>
Mon, 22 Sep 2025 06:22:48 +0000 (15:22 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Mon, 22 Sep 2025 14:07:06 +0000 (23:07 +0900)
In systemd <= 257, each set_audit tristate value had special meaning,
- true: enable the kernel audit subsystem,
- false: disable the kernel audit subsystem,
- negative: keep the current kernel audit subsystem state.

And the default is true, rather than negative. So, users sometimes
explicitly pass an empty string to Audit= setting to keep the state.

But since f48cf2a96dfdc23fe30ba0f870125fe55cab64c7 (v258), the negative
value is mistakenly used as 'really unspecified' even if an empty string
is explicitly specified.

This makes negative values handled as unspecified as usual, and assign a new
positive value AUDIT_KEEP for when an empty string is explicitly specified.
Also, make the Audit= setting accept "keep" setting, and suggest to use "keep"
rather than an empty string.

Fixes a regression caused by f48cf2a96dfdc23fe30ba0f870125fe55cab64c7 (v258).
Fixes #39057.

man/journald.conf.xml
src/journal/journald-audit.c
src/journal/journald-audit.h
src/journal/journald-config.c
src/journal/journald-config.h
src/journal/journald-forward.h
src/journal/journald-gperf.gperf

index 1a68ba869850d0d7be01a4b744eb7d4444ccfa4d..1d615b110dc27cf2a260f83b2f604294122cc790 100644 (file)
       <varlistentry>
         <term><varname>Audit=</varname></term>
 
-        <listitem><para>Takes a boolean value. If enabled <command>systemd-journald</command> will turn on
-        kernel auditing on start-up. If disabled it will turn it off. If unset it will neither enable nor
-        disable it, leaving the previous state unchanged.  This means if another tool turns on auditing even
-        if <command>systemd-journald</command> left it off, it will still collect the generated
-        messages. Defaults to on in the default journal namespace, and unset otherwise.</para>
+        <listitem><para>Takes a boolean value or special value <literal>keep</literal>. If enabled
+        <command>systemd-journald</command> will turn on kernel auditing on start-up. If disabled it will
+        turn it off. When <literal>keep</literal> it will neither enable nor disable it, leaving the previous
+        state unchanged. This means if another tool turns on auditing even if
+        <command>systemd-journald</command> left it off, it will still collect the generated messages.
+        Defaults to yes in the default journal namespace, and <literal>keep</literal> otherwise.</para>
+
+        <!-- Explicit assignment of an empty string is equivalent to 'keep', for backward compatibility. -->
 
         <para>Note that this option does not control whether <command>systemd-journald</command> collects
         generated audit records, it just controls whether it tells the kernel to generate them. If you need
index 6f08875ca303f7459f20dca06f246ee5a97771c3..eec072d32f376e06ddfad18e56298e4fa6caf876 100644 (file)
@@ -465,10 +465,14 @@ static int manager_set_kernel_audit(Manager *m) {
 
         assert(m);
         assert(m->audit_fd >= 0);
+        assert(m->config.set_audit >= 0);
 
-        if (m->config.set_audit < 0)
+        if (m->config.set_audit == AUDIT_KEEP)
                 return 0;
 
+        /* In the following, we can handle 'set_audit' as a boolean. */
+        assert(IN_SET(m->config.set_audit, AUDIT_NO, AUDIT_YES));
+
         struct {
                 union {
                         struct nlmsghdr header;
@@ -557,7 +561,7 @@ int manager_open_audit(Manager *m) {
         return 0;
 }
 
-void manager_reset_kernel_audit(Manager *m, int old_set_audit) {
+void manager_reset_kernel_audit(Manager *m, AuditSetMode old_set_audit) {
         assert(m);
 
         if (m->audit_fd < 0)
index 1f1b778e372f147836c8c59fac40f7407ee43bba..339ae14a24caf4f41149157ff02fdda4d989b06d 100644 (file)
@@ -10,4 +10,4 @@ void manager_process_audit_message(Manager *m, const void *buffer, size_t buffer
 void process_audit_string(Manager *m, int type, const char *data, size_t size);
 
 int manager_open_audit(Manager *m);
-void manager_reset_kernel_audit(Manager *m, int old_set_audit);
+void manager_reset_kernel_audit(Manager *m, AuditSetMode old_set_audit);
index b43ad26ce30ac18313523c2d4e9d49897094e6af..8cffec880b23c443ac6aacafa5b5972d2bc0e2d3 100644 (file)
@@ -46,7 +46,7 @@ void journal_config_set_defaults(JournalConfig *c) {
                 .compress.threshold_bytes = UINT64_MAX,
                 .seal = -1,
                 .read_kmsg = -1,
-                .set_audit = -1,
+                .set_audit = _AUDIT_SET_MODE_INVALID,
                 .ratelimit_interval = DEFAULT_RATE_LIMIT_INTERVAL,
                 .ratelimit_burst = DEFAULT_RATE_LIMIT_BURST,
                 .forward_to_syslog = -1,
@@ -123,7 +123,7 @@ void manager_merge_configs(Manager *m) {
         MERGE_NON_NEGATIVE(read_kmsg, !m->namespace);
         /* By default, kernel auditing is enabled by the main namespace instance, and not controlled by
          * non-default namespace instances. */
-        MERGE_NON_NEGATIVE(set_audit, m->namespace ? -1 : true);
+        MERGE_NON_NEGATIVE(set_audit, m->namespace ? AUDIT_KEEP : AUDIT_YES);
         MERGE_NON_ZERO(sync_interval_usec, DEFAULT_SYNC_INTERVAL_USEC);
 
         /* TODO: also merge them when comdline or credentials support to configure them. */
@@ -402,6 +402,16 @@ static const char* const split_mode_table[_SPLIT_MAX] = {
 DEFINE_STRING_TABLE_LOOKUP(split_mode, SplitMode);
 DEFINE_CONFIG_PARSE_ENUM(config_parse_split_mode, split_mode, SplitMode);
 
+static const char* const audit_set_mode_table[_AUDIT_SET_MODE_MAX] = {
+        [AUDIT_NO]   = "no",
+        [AUDIT_YES]  = "yes",
+        [AUDIT_KEEP] = "keep",
+};
+
+DEFINE_PRIVATE_STRING_TABLE_LOOKUP_FROM_STRING_WITH_BOOLEAN(audit_set_mode, AuditSetMode, AUDIT_YES);
+/* For backward compatibility, an empty string has special meaning and equals to 'keep'. */
+DEFINE_CONFIG_PARSE_ENUM_WITH_DEFAULT(config_parse_audit_set_mode, audit_set_mode, AuditSetMode, AUDIT_KEEP);
+
 int config_parse_line_max(
                 const char *unit,
                 const char *filename,
index c396c3a56035e8a9ce9de6795c683739f3a6b919..988badfb8a063f6d961f085a9413f2d52fa1b78d 100644 (file)
@@ -27,6 +27,14 @@ typedef struct JournalCompressOptions {
         uint64_t threshold_bytes;
 } JournalCompressOptions;
 
+typedef enum AuditSetMode {
+        AUDIT_NO = 0, /* Disables the kernel audit subsystem on start. */
+        AUDIT_YES,    /* Enables the kernel audit subsystem on start. */
+        AUDIT_KEEP,   /* Keep the current kernel audit subsystem state. */
+        _AUDIT_SET_MODE_MAX,
+        _AUDIT_SET_MODE_INVALID = -EINVAL,
+} AuditSetMode;
+
 typedef struct JournalConfig {
         /* Storage=, cred: journal.storage */
         Storage storage;
@@ -37,7 +45,7 @@ typedef struct JournalConfig {
         /* ReadKMsg= */
         int read_kmsg;
         /* Audit= */
-        int set_audit;
+        AuditSetMode set_audit;
         /* SyncIntervalSec= */
         usec_t sync_interval_usec;
         /* RateLimitIntervalSec= */
@@ -102,3 +110,4 @@ CONFIG_PARSER_PROTOTYPE(config_parse_line_max);
 CONFIG_PARSER_PROTOTYPE(config_parse_compress);
 CONFIG_PARSER_PROTOTYPE(config_parse_forward_to_socket);
 CONFIG_PARSER_PROTOTYPE(config_parse_split_mode);
+CONFIG_PARSER_PROTOTYPE(config_parse_audit_set_mode);
index 65458f46ab0a72b93a8c9e49dfd2a32845c611e3..ef597bbf114d5998048c3505de0d1faf8c707f6c 100644 (file)
@@ -6,6 +6,7 @@
 
 typedef enum Storage Storage;
 typedef enum SplitMode SplitMode;
+typedef enum AuditSetMode AuditSetMode;
 typedef struct JournalCompressOptions JournalCompressOptions;
 typedef struct JournalConfig JournalConfig;
 
index 23caa287ffd6460938092cbb9435fcc1b8bcbe04..22d4e683ccac41f71dd212acefdfc437f689088e 100644 (file)
@@ -23,7 +23,7 @@ Journal.Storage,              config_parse_storage,           0, offsetof(Journa
 Journal.Compress,             config_parse_compress,          0, offsetof(JournalConfig, compress)
 Journal.Seal,                 config_parse_tristate,          0, offsetof(JournalConfig, seal)
 Journal.ReadKMsg,             config_parse_tristate,          0, offsetof(JournalConfig, read_kmsg)
-Journal.Audit,                config_parse_tristate,          0, offsetof(JournalConfig, set_audit)
+Journal.Audit,                config_parse_audit_set_mode,    0, offsetof(JournalConfig, set_audit)
 Journal.SyncIntervalSec,      config_parse_sec,               0, offsetof(JournalConfig, sync_interval_usec)
 # The following is a legacy name for compatibility
 Journal.RateLimitInterval,    config_parse_sec,               0, offsetof(JournalConfig, ratelimit_interval)