]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
compress: split compress_blob() and friends to minimize dlopen dependencies
authorYu Watanabe <watanabe.yu+github@gmail.com>
Thu, 9 Jul 2026 02:17:56 +0000 (11:17 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Fri, 10 Jul 2026 07:35:19 +0000 (16:35 +0900)
Previously, even though sd-journal does not support bzip2 and gzip
compression, the dlopen ELF notes for those libraries were still being
attached to libsystemd.so and various journal-handling executables.
This occurred because the unified compression/decompression interfaces
handled all formats unconditionally, causing the compiler and linker to
pull in all associated dlopen notes across the board.

To resolve this, split these functions into generic and journal-specific
variants (e.g., introducing compress_blob_journal() and decompress_blob_journal()).
The journal-specific variants only handle formats actually supported by
the journal (LZ4, XZ, and ZSTD).

By updating sd-journal, journald, journalctl, and related utilities to
use these new `_journal` interfaces and switching them to the narrower
COMPRESS_JOURNAL_NOTE macro, we ensure that unnecessary dlopen notes
(for bzip2 and gzip) are no longer embedded into these binaries.

12 files changed:
src/basic/compress.c
src/basic/compress.h
src/basic/dlopen-note.h
src/journal-remote/journal-gatewayd.c
src/journal/bsod.c
src/journal/journalctl.c
src/journal/journald.c
src/libsystemd/sd-journal/journal-file.c
src/libsystemd/sd-journal/journal-verify.c
src/login/loginctl.c
src/machine/machinectl.c
src/network/networkctl.c

index 5936a13f8e80eef3bda5e52951545e80a69aaf8b..2bc11f48bc230e496d550e69443ebf1d8bdb2a23 100644 (file)
@@ -254,6 +254,19 @@ Compression compression_from_filename(const char *filename) {
         return c;
 }
 
+bool compression_supported_journal(Compression c) {
+        static const unsigned supported =
+                (1U << COMPRESSION_NONE) |
+                (1U << COMPRESSION_XZ) * HAVE_XZ |
+                (1U << COMPRESSION_LZ4) * HAVE_LZ4 |
+                (1U << COMPRESSION_ZSTD) * HAVE_ZSTD;
+
+        assert(c >= 0);
+        assert(c < _COMPRESSION_MAX);
+
+        return BIT_SET(supported, c);
+}
+
 bool compression_supported(Compression c) {
         static const unsigned supported =
                 (1U << COMPRESSION_NONE) |
@@ -639,7 +652,7 @@ static int compress_blob_bzip2(
 #endif
 }
 
-int compress_blob(
+int compress_blob_journal(
                 Compression compression,
                 const void *src, uint64_t src_size,
                 void *dst, size_t dst_alloc_size, size_t *dst_size, int level) {
@@ -651,12 +664,23 @@ int compress_blob(
                 return compress_blob_lz4(src, src_size, dst, dst_alloc_size, dst_size, level);
         case COMPRESSION_ZSTD:
                 return compress_blob_zstd(src, src_size, dst, dst_alloc_size, dst_size, level);
+        default:
+                return -EOPNOTSUPP;
+        }
+}
+
+int compress_blob(
+                Compression compression,
+                const void *src, uint64_t src_size,
+                void *dst, size_t dst_alloc_size, size_t *dst_size, int level) {
+
+        switch (compression) {
         case COMPRESSION_GZIP:
                 return compress_blob_gzip(src, src_size, dst, dst_alloc_size, dst_size, level);
         case COMPRESSION_BZIP2:
                 return compress_blob_bzip2(src, src_size, dst, dst_alloc_size, dst_size, level);
         default:
-                return -EOPNOTSUPP;
+                return compress_blob_journal(compression, src, src_size, dst, dst_alloc_size, dst_size, level);
         }
 }
 
@@ -1033,7 +1057,7 @@ static int decompress_blob_bzip2(
 #endif
 }
 
-int decompress_blob(
+int decompress_blob_journal(
                 Compression compression,
                 const void *src,
                 uint64_t src_size,
@@ -1054,6 +1078,20 @@ int decompress_blob(
                 return decompress_blob_zstd(
                                 src, src_size,
                                 dst, dst_size, dst_max);
+        default:
+                return -EPROTONOSUPPORT;
+        }
+}
+
+int decompress_blob(
+                Compression compression,
+                const void *src,
+                uint64_t src_size,
+                void **dst,
+                size_t *dst_size,
+                size_t dst_max) {
+
+        switch (compression) {
         case COMPRESSION_GZIP:
                 return decompress_blob_gzip(
                                 src, src_size,
@@ -1063,7 +1101,10 @@ int decompress_blob(
                                 src, src_size,
                                 dst, dst_size, dst_max);
         default:
-                return -EPROTONOSUPPORT;
+                return decompress_blob_journal(
+                                compression,
+                                src, src_size,
+                                dst, dst_size, dst_max);
         }
 }
 
@@ -1452,7 +1493,7 @@ static int decompress_startswith_bzip2(
 #endif
 }
 
-int decompress_startswith(
+int decompress_startswith_journal(
                 Compression compression,
                 const void *src, uint64_t src_size,
                 void **buffer,
@@ -1466,12 +1507,25 @@ int decompress_startswith(
                 return decompress_startswith_lz4(src, src_size, buffer, prefix, prefix_len, extra);
         case COMPRESSION_ZSTD:
                 return decompress_startswith_zstd(src, src_size, buffer, prefix, prefix_len, extra);
+        default:
+                return -EOPNOTSUPP;
+        }
+}
+
+int decompress_startswith(
+                Compression compression,
+                const void *src, uint64_t src_size,
+                void **buffer,
+                const void *prefix, size_t prefix_len,
+                uint8_t extra) {
+
+        switch (compression) {
         case COMPRESSION_GZIP:
                 return decompress_startswith_gzip(src, src_size, buffer, prefix, prefix_len, extra);
         case COMPRESSION_BZIP2:
                 return decompress_startswith_bzip2(src, src_size, buffer, prefix, prefix_len, extra);
         default:
-                return -EOPNOTSUPP;
+                return decompress_startswith_journal(compression, src, src_size, buffer, prefix, prefix_len, extra);
         }
 }
 
index 52fdf3aa27292030fb1cef12d81615617981e297..e25ab6d9a424d41a74de53c93c1852a3be955dbf 100644 (file)
@@ -27,6 +27,7 @@ Compression compression_from_string_harder(const char *s);
  * filename does not carry a recognized compression suffix. */
 Compression compression_from_filename(const char *filename);
 
+bool compression_supported_journal(Compression c);
 bool compression_supported(Compression c);
 
 /* Buffer size used by streaming compression APIs and pipeline stages that feed into them. Sized to
@@ -59,9 +60,17 @@ Compression compressor_type(const Compressor *c);
 
 /* Blob compression/decompression */
 
+int compress_blob_journal(
+                Compression compression,
+                const void *src, uint64_t src_size,
+                void *dst, size_t dst_alloc_size, size_t *dst_size, int level);
 int compress_blob(Compression compression,
                   const void *src, uint64_t src_size,
                   void *dst, size_t dst_alloc_size, size_t *dst_size, int level);
+int decompress_blob_journal(
+                Compression compression,
+                const void *src, uint64_t src_size,
+                void **dst, size_t *dst_size, size_t dst_max);
 int decompress_blob(Compression compression,
                     const void *src, uint64_t src_size,
                     void **dst, size_t *dst_size, size_t dst_max);
@@ -69,6 +78,12 @@ int decompress_blob(Compression compression,
 int decompress_zlib_raw(const void *src, uint64_t src_size,
                         void *dst, size_t dst_size, int wbits);
 
+int decompress_startswith_journal(
+                Compression compression,
+                const void *src, uint64_t src_size,
+                void **buffer,
+                const void *prefix, size_t prefix_len,
+                uint8_t extra);
 int decompress_startswith(Compression compression,
                           const void *src, uint64_t src_size,
                           void **buffer,
index 41661939a1fab34511ba68b7bd62b6a7efb098ae..6d3bd5e2bc9eb46261405225a02b3ac2f7f9740f 100644 (file)
         LIBZSTD_NOTE(priority)
 
 #define COMPRESS_DEFAULT_NOTE                           \
+        COMPRESS_JOURNAL_NOTE;                          \
         LIBBZ2_NOTE(suggested);                         \
+        LIBZ_NOTE(suggested)
+
+#define COMPRESS_JOURNAL_NOTE                           \
         LIBLZ4_NOTE(COMPRESSION_PRIORITY_LZ4);          \
         LIBLZMA_NOTE(COMPRESSION_PRIORITY_XZ);          \
-        LIBZ_NOTE(suggested);                           \
         LIBZSTD_NOTE(COMPRESSION_PRIORITY_ZSTD)
index 9def4a3bc9fa0e9ded5c562454b51f35a6b0d8c9..8a6e59c8d768e1eb78a1b05324c0b0c8ff5ced67 100644 (file)
@@ -1259,7 +1259,7 @@ static int run(int argc, char *argv[]) {
                 MHD_USE_THREAD_PER_CONNECTION;
         int r, n;
 
-        COMPRESS_DEFAULT_NOTE;
+        COMPRESS_JOURNAL_NOTE;
         LIBGNUTLS_NOTE(suggested);
 
         log_setup();
index 9a9067088c0ed84f71037c0227c3c92cd80b69f3..78093844fa6c8385ab25641e413ccfc12d1b300d 100644 (file)
@@ -288,7 +288,7 @@ static int run(int argc, char *argv[]) {
         _cleanup_free_ char *message = NULL;
         int r;
 
-        COMPRESS_DEFAULT_NOTE;
+        COMPRESS_JOURNAL_NOTE;
         LIBQRENCODE_NOTE(suggested);
 
         log_setup();
index bb5b376a933d9d4fbdd1d2ed2cd7eb67e970c445..b407a77d97058051df8a0fce7313371e4606dc2d 100644 (file)
@@ -1022,7 +1022,7 @@ static int run(int argc, char *argv[]) {
         _cleanup_strv_free_ char **args = NULL;
         int r;
 
-        COMPRESS_DEFAULT_NOTE;
+        COMPRESS_JOURNAL_NOTE;
         LIBACL_NOTE(recommended);
         LIBBLKID_NOTE(recommended);
         LIBCRYPTSETUP_NOTE(suggested);
index 3cab48f6b7b718346902819fa15ff4995b1ac293..ec095684df0ab26b5095d49f5eda6c9d9efe68f8 100644 (file)
@@ -26,7 +26,7 @@ static int run(int argc, char *argv[]) {
         LogTarget log_target;
         int r;
 
-        COMPRESS_DEFAULT_NOTE;
+        COMPRESS_JOURNAL_NOTE;
         LIBACL_NOTE(recommended);
         LIBCRYPTO_NOTE(suggested);
         LIBPCRE2_NOTE(suggested);
index 93b2c90c15214f47466b2c5731bc9cff37b3bd45..b0df06d75aa0a6699f7f5a329eda13fbc79c83ff 100644 (file)
@@ -365,7 +365,7 @@ static Compression getenv_compression(void) {
                 return DEFAULT_COMPRESSION;
         }
 
-        if (!compression_supported(c)) {
+        if (!compression_supported_journal(c)) {
                 log_debug("Unsupported compression algorithm specified, ignoring: %s", e);
                 return DEFAULT_COMPRESSION;
         }
@@ -1861,7 +1861,7 @@ static int maybe_compress_payload(
                 return 0;
         }
 
-        r = compress_blob(c, src, size, dst, size - 1, rsize, /* level= */ -1);
+        r = compress_blob_journal(c, src, size, dst, size - 1, rsize, /* level= */ -1);
         if (r < 0)
                 return log_debug_errno(r, "Failed to compress data object using %s, ignoring: %m", compression_to_string(c));
 
@@ -1983,7 +1983,7 @@ static int maybe_decompress_payload(
                 int r;
 
                 if (field) {
-                        r = decompress_startswith(compression, payload, size, &f->compress_buffer, field,
+                        r = decompress_startswith_journal(compression, payload, size, &f->compress_buffer, field,
                                                   field_length, '=');
                         if (r < 0)
                                 return log_debug_errno(r,
@@ -2003,7 +2003,7 @@ static int maybe_decompress_payload(
                                 return 1;
                 }
 
-                r = decompress_blob(compression, payload, size, &f->compress_buffer, &rsize, DATA_SIZE_MAX);
+                r = decompress_blob_journal(compression, payload, size, &f->compress_buffer, &rsize, DATA_SIZE_MAX);
                 if (r < 0)
                         return r;
 
index d214a68e686676b02e5fe11f736b5e86c23629a0..79061940b399066119d84eb6de1fc3d4a503b117 100644 (file)
@@ -125,7 +125,7 @@ static int hash_payload(JournalFile *f, Object *o, uint64_t offset, const uint8_
                 _cleanup_free_ void *b = NULL;
                 size_t b_size;
 
-                r = decompress_blob(c, src, size, &b, &b_size, DATA_SIZE_MAX);
+                r = decompress_blob_journal(c, src, size, &b, &b_size, DATA_SIZE_MAX);
                 if (r < 0) {
                         error_errno(offset, r, "%s decompression failed: %m",
                                     compression_to_string(c));
index be670254211667250823cbfd63338f2e8505dd65..566f4db877d938a2c07ced0558d191c033fdd660 100644 (file)
@@ -1662,7 +1662,7 @@ static int run(int argc, char *argv[]) {
         char **args = NULL;
         int r;
 
-        COMPRESS_DEFAULT_NOTE;
+        COMPRESS_JOURNAL_NOTE;
 
         setlocale(LC_ALL, "");
         log_setup();
index dc2381fc84a8a84c28fb3c795909ab6bb14a0b6c..19ad385733972ebcf3a20ae999a2e692dd94d254 100644 (file)
@@ -2635,7 +2635,7 @@ static int run(int argc, char *argv[]) {
         _cleanup_strv_free_ char **args = NULL;
         int r;
 
-        COMPRESS_DEFAULT_NOTE;
+        COMPRESS_JOURNAL_NOTE;
         LIBSELINUX_NOTE(recommended);
 
         setlocale(LC_ALL, "");
index f85c74b6afac13aa5c27cac5154fc859746b4701..f7a6e6eef7619550a6a2128edd740b9c16a5cc6a 100644 (file)
@@ -209,7 +209,7 @@ static int run(int argc, char* argv[]) {
         char **args = NULL;
         int r;
 
-        COMPRESS_DEFAULT_NOTE;
+        COMPRESS_JOURNAL_NOTE;
         LIBSELINUX_NOTE(recommended);
 
         log_setup();