]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-settings, config: Use native CPU endianess in binary config file
authorTimo Sirainen <timo.sirainen@open-xchange.com>
Mon, 24 Feb 2025 11:28:10 +0000 (13:28 +0200)
committertimo.sirainen <timo.sirainen@open-xchange.com>
Mon, 12 May 2025 15:51:47 +0000 (15:51 +0000)
The binary config file is never shared between different servers, so for
performance it's better to just use native endianess.

src/config/config-dump-full.c
src/lib-master/test-master-service-settings.c
src/lib-settings/settings.c

index 23cf56b7449e87d6170c323ca3daa6057f38131e..26d9a906f40fd82f09a48a2b3ffb986385c25dea 100644 (file)
    Config binary file format:
 
    The settings size numbers do not include the size integer itself.
+   All the numbers are in native CPU endianess.
 
    "DOVECOT-CONFIG\t1.0\n"
-   <64bit big-endian: settings full size>
+   <64bit: settings full size>
 
-   <32bit big-endian: number of paths used for caching>
+   <32bit: number of paths used for caching>
    Repeat for "number of paths":
      <NUL-terminated string: path>
-     <64bit big-endian: inode>
-     <64bit big-endian: size>
-     <32bit big-endian: mtime UNIX timestamp>
-     <32bit big-endian: mtime nsecs>
-     <32bit big-endian: ctime UNIX timestamp>
-     <32bit big-endian: ctime nsecs>
-
-   <32bit big-endian: event filter strings count>
+     <64bit: inode>
+     <64bit: size>
+     <32bit: mtime UNIX timestamp>
+     <32bit: mtime nsecs>
+     <32bit: ctime UNIX timestamp>
+     <32bit: ctime nsecs>
+
+   <32bit: event filter strings count>
    Repeat for "event filter strings count":
      <NUL-terminated string: event filter string>
      <NUL-terminated string: override event filter string>
 
    Repeat until "settings full size" is reached:
-     <64bit big-endian: settings block size>
+     <64bit: settings block size>
      <NUL-terminated string: setting block name>
 
-     <32bit big-endian: settings count>
+     <32bit: settings count>
      <NUL-terminated string: key>[settings count]
 
-     <32bit big-endian: filter count>
+     <32bit: filter count>
      Repeat for "filter count":
-       <64bit big-endian: filter settings size>
+       <64bit: filter settings size>
        <NUL-terminated string: error string - if client attempts to access this
                               settings block, it must fail with this error.
                               NUL = no error, followed by settings>
-       <32bit big-endian: include group count>
+       <32bit: include group count>
        Repeat for "include group count":
          <NUL-terminated string: group label>
          <NUL-terminated string: group name>
        Repeat until "filter settings size" is reached:
-         <32bit big-endian: key index number>
+         <32bit: key index number>
         [+|$ <strlist/boollist key>]
         <NUL-terminated string: value>
      Repeat for "filter count":
-       <32bit big-endian: event filter string index number>
+       <32bit: event filter string index number>
      Repeat for "filter count":
-       <64bit big-endian: filter settings offset>
+       <64bit: filter settings offset>
      <trailing safety NUL>
 
    The order of filters is important in the output. lib-settings applies the
@@ -115,8 +116,8 @@ struct dump_context {
 static int output_blob_size(struct ostream *output, uoff_t blob_size_offset)
 {
        i_assert(output->offset >= blob_size_offset + sizeof(uint64_t));
-       uint64_t blob_size = cpu64_to_be(output->offset -
-                                        (blob_size_offset + sizeof(uint64_t)));
+       uint64_t blob_size = output->offset -
+               (blob_size_offset + sizeof(uint64_t));
        if (o_stream_pwrite(output, &blob_size, sizeof(blob_size),
                            blob_size_offset) < 0) {
                i_error("o_stream_pwrite(%s) failed: %s",
@@ -151,21 +152,21 @@ config_dump_full_write_cache_paths(struct ostream *output,
                return;
        }
 
-       num32 = cpu32_to_be(array_count(config_parsed_get_paths(config)));
+       num32 = array_count(config_parsed_get_paths(config));
        o_stream_nsend(output, &num32, sizeof(num32));
        array_foreach(config_parsed_get_paths(config), path) {
                o_stream_nsend(output, path->path, strlen(path->path) + 1);
-               uint64_t num64 = cpu32_to_be(path->st.st_ino);
+               uint64_t num64 = path->st.st_ino;
                o_stream_nsend(output, &num64, sizeof(num64));
-               num64 = cpu32_to_be(path->st.st_size);
+               num64 = path->st.st_size;
                o_stream_nsend(output, &num64, sizeof(num64));
-               num32 = cpu32_to_be(path->st.st_mtime);
+               num32 = path->st.st_mtime;
                o_stream_nsend(output, &num32, sizeof(num32));
-               num32 = cpu32_to_be(ST_MTIME_NSEC(path->st));
+               num32 = ST_MTIME_NSEC(path->st);
                o_stream_nsend(output, &num32, sizeof(num32));
-               num32 = cpu32_to_be(path->st.st_ctime);
+               num32 = path->st.st_ctime;
                o_stream_nsend(output, &num32, sizeof(num32));
-               num32 = cpu32_to_be(ST_CTIME_NSEC(path->st));
+               num32 = ST_CTIME_NSEC(path->st);
                o_stream_nsend(output, &num32, sizeof(num32));
        }
 
@@ -250,8 +251,8 @@ config_dump_full_write_filters(struct ostream *output,
 
        while (filters[filter_count] != NULL) filter_count++;
 
-       uint32_t filter_count_be32 = cpu32_to_be(filter_count);
-       o_stream_nsend(output, &filter_count_be32, sizeof(filter_count_be32));
+       uint32_t filter_count_32 = filter_count;
+       o_stream_nsend(output, &filter_count_32, sizeof(filter_count_32));
 
        /* the first filter is the global empty filter */
        o_stream_nsend(output, "", 1);
@@ -277,8 +278,8 @@ config_dump_full_write_keys(struct ostream *output,
 {
        unsigned int count = setting_parser_info_get_define_count(info);
 
-       uint32_t count_be32 = cpu32_to_be(count);
-       o_stream_nsend(output, &count_be32, sizeof(count_be32));
+       uint32_t count_32 = count;
+       o_stream_nsend(output, &count_32, sizeof(count_32));
 
        for (unsigned int i = 0; i < count; i++) {
                const char *key = info->defines[i].key;
@@ -356,14 +357,14 @@ config_dump_full_stdout_callback(const struct config_export_setting *set,
 
 static void config_include_groups_dump(struct dump_context *ctx)
 {
-       uint32_t include_count_be32 = 0;
+       uint32_t include_count_32 = 0;
        if (ctx->include_groups == NULL) {
-               o_stream_nsend(ctx->output, &include_count_be32,
-                              sizeof(include_count_be32));
+               o_stream_nsend(ctx->output, &include_count_32,
+                              sizeof(include_count_32));
        } else {
-               include_count_be32 = cpu32_to_be(array_count(ctx->include_groups));
-               o_stream_nsend(ctx->output, &include_count_be32,
-                              sizeof(include_count_be32));
+               include_count_32 = array_count(ctx->include_groups);
+               o_stream_nsend(ctx->output, &include_count_32,
+                              sizeof(include_count_32));
 
                const struct config_include_group *group;
                array_foreach(ctx->include_groups, group) {
@@ -408,7 +409,7 @@ static void config_dump_full_callback(const struct config_export_setting *set,
 
        config_dump_full_write_filter(ctx);
 
-       uint32_t key_be32 = cpu32_to_be(set->key_define_idx);
+       uint32_t key_32 = set->key_define_idx;
        if (ctx->delayed_output != NULL &&
            ((str_begins(set->key, "passdb", &suffix) &&
              (suffix[0] == '\0' || suffix[0] == '/')) ||
@@ -416,12 +417,12 @@ static void config_dump_full_callback(const struct config_export_setting *set,
              (suffix[0] == '\0' || suffix[0] == '/')))) {
                /* For backwards compatibility: global passdbs and userdbs are
                   added after per-protocol ones, not before. */
-               str_append_data(ctx->delayed_output, &key_be32,
-                               sizeof(key_be32));
+               str_append_data(ctx->delayed_output, &key_32,
+                               sizeof(key_32));
                str_append_data(ctx->delayed_output, set->value,
                                strlen(set->value)+1);
        } else {
-               o_stream_nsend(ctx->output, &key_be32, sizeof(key_be32));
+               o_stream_nsend(ctx->output, &key_32, sizeof(key_32));
                const struct setting_define *def =
                        &ctx->info->defines[set->key_define_idx];
                if (def->type == SET_STRLIST || def->type == SET_BOOLLIST) {
@@ -496,7 +497,7 @@ config_dump_full_handle_error(struct dump_context *dump_ctx,
        }
 
        size_t error_len = strlen(error) + 1;
-       uint64_t blob_size = cpu64_to_be(error_len + 4);
+       uint64_t blob_size = error_len + 4;
        o_stream_nsend(output, &blob_size, sizeof(blob_size));
        o_stream_nsend(output, error, error_len);
        uint32_t include_group_count = 0;
@@ -515,8 +516,8 @@ struct config_dump_full_context {
        struct config_filter_parser *const *filters;
        uint32_t filter_output_count;
 
-       uint32_t *filter_indexes_be32;
-       uint64_t *filter_offsets_be64;
+       uint32_t *filter_indexes_32;
+       uint64_t *filter_offsets_64;
 };
 
 enum config_dump_type {
@@ -635,21 +636,20 @@ config_dump_full_sections(struct config_dump_full_context *ctx,
                }
                config_export_free(&export_ctx);
                if (dump_ctx.filter_written) {
-                       ctx->filter_indexes_be32[ctx->filter_output_count] =
-                               cpu32_to_be(i);
-                       ctx->filter_offsets_be64[ctx->filter_output_count] =
-                               cpu64_to_be(start_offset);
+                       ctx->filter_indexes_32[ctx->filter_output_count] = i;
+                       ctx->filter_offsets_64[ctx->filter_output_count] =
+                               start_offset;
                        ctx->filter_output_count++;
                }
        }
 
        if (delayed_filter != NULL && str_len(delayed_filter) > 0) {
-               ctx->filter_indexes_be32[ctx->filter_output_count] =
+               ctx->filter_indexes_32[ctx->filter_output_count] =
                        0; /* empty/global filter */
-               ctx->filter_offsets_be64[ctx->filter_output_count] =
-                       cpu64_to_be(output->offset);
+               ctx->filter_offsets_64[ctx->filter_output_count] =
+                       output->offset;
 
-               uint64_t blob_size = cpu64_to_be(5 + str_len(delayed_filter));
+               uint64_t blob_size = 5 + str_len(delayed_filter);
                o_stream_nsend(output, &blob_size, sizeof(blob_size));
                o_stream_nsend(output, "", 1); /* no error */
                uint32_t include_group_count = 0;
@@ -780,8 +780,8 @@ int config_dump_full(struct config_parsed *config,
        uint32_t max_filter_count = 0;
        while (ctx.filters[max_filter_count] != NULL) max_filter_count++;
 
-       ctx.filter_indexes_be32 = t_new(uint32_t, max_filter_count);
-       ctx.filter_offsets_be64 = t_new(uint64_t, max_filter_count);
+       ctx.filter_indexes_32 = t_new(uint32_t, max_filter_count);
+       ctx.filter_offsets_64 = t_new(uint64_t, max_filter_count);
 
        ARRAY_TYPE(config_include_group) groups;
        t_array_init(&groups, 8);
@@ -824,9 +824,9 @@ int config_dump_full(struct config_parsed *config,
 
                uoff_t blob_size_offset = output->offset;
                /* 2. Write global settings in config - use an empty filter */
-               ctx.filter_indexes_be32[ctx.filter_output_count] = 0;
-               ctx.filter_offsets_be64[ctx.filter_output_count] =
-                       cpu64_to_be(blob_size_offset);
+               ctx.filter_indexes_32[ctx.filter_output_count] = 0;
+               ctx.filter_offsets_64[ctx.filter_output_count] =
+                       blob_size_offset;
                ctx.filter_output_count++;
 
                if (config_parsed_get_includes(config, filter_parser,
@@ -887,18 +887,18 @@ int config_dump_full(struct config_parsed *config,
                        break;
 
                if (dest != CONFIG_DUMP_FULL_DEST_STDOUT) {
-                       o_stream_nsend(output, ctx.filter_indexes_be32,
-                                      sizeof(ctx.filter_indexes_be32[0]) *
+                       o_stream_nsend(output, ctx.filter_indexes_32,
+                                      sizeof(ctx.filter_indexes_32[0]) *
                                       ctx.filter_output_count);
-                       o_stream_nsend(output, ctx.filter_offsets_be64,
-                                      sizeof(ctx.filter_offsets_be64[0]) *
+                       o_stream_nsend(output, ctx.filter_offsets_64,
+                                      sizeof(ctx.filter_offsets_64[0]) *
                                       ctx.filter_output_count);
                        /* safety NUL at the end of the block */
                        o_stream_nsend(output, "", 1);
                }
 
                if (dest != CONFIG_DUMP_FULL_DEST_STDOUT) {
-                       filter_count = cpu32_to_be(ctx.filter_output_count);
+                       filter_count = ctx.filter_output_count;
                        if (o_stream_pwrite(output, &filter_count,
                                            sizeof(filter_count),
                                            filter_count_offset) < 0) {
index 51a7f6183ecfc788a9b3f5440fa37bd633003659..87a259fd8861f83d51e97886bfdc3ed427e20aa8 100644 (file)
 
 #define DATA(data) (const unsigned char *)data"\xff", sizeof(data"\xff")-2
 
+/* we only need to use 1 byte */
+#ifdef WORDS_BIGENDIAN
+#  define NUM64(n) "\x00\x00\x00\x00\x00\x00\x00"n
+#  define NUM32(n) "\x00\x00\x00"n
+#else
+#  define NUM64(n) n"\x00\x00\x00\x00\x00\x00\x00"
+#  define NUM32(n) n"\x00\x00\x00"
+#endif
+
 static const struct {
        const unsigned char *data;
        size_t size;
@@ -26,289 +35,289 @@ static const struct {
 
        /* full file size = 1, but file is still truncated */
        { DATA("DOVECOT-CONFIG\t1.0\n" // 19 bytes
-              "\x00\x00\x00\x00\x00\x00\x00\x01"), // full size
+              NUM64("\x01")), // full size
          "Full size mismatch" },
 
        /* cache path count is truncated */
        { DATA("DOVECOT-CONFIG\t1.0\n"
-              "\x00\x00\x00\x00\x00\x00\x00\x04" // full size
+              NUM64("\x04") // full size
               "\x00\x00\x00"), // cache path count
          "Full size mismatch" },
 
        /* event filter count is truncated */
        { DATA("DOVECOT-CONFIG\t1.0\n"
-              "\x00\x00\x00\x00\x00\x00\x00\x08" // full size
-              "\x00\x00\x00\x00" // cache path count
+              NUM64("\x08") // full size
+              NUM32("\x00") // cache path count
               "\x00\x00\x00"), // event filter count
          "Full size mismatch" },
 
        /* event filter strings are truncated */
        { DATA("DOVECOT-CONFIG\t1.0\n"
-              "\x00\x00\x00\x00\x00\x00\x00\x08" // full size
-              "\x00\x00\x00\x00" // cache path count
-              "\x00\x00\x10\x00"), // event filter count
+              NUM64("\x08") // full size
+              NUM32("\x00") // cache path count
+              NUM32("\x01")), // event filter count
          "'filter string' points outside area" },
 
        /* full file size is 7 bytes, which makes the first block size
           truncated, since it needs 8 bytes */
        { DATA("DOVECOT-CONFIG\t1.0\n"
-              "\x00\x00\x00\x00\x00\x00\x00\x11" // full size
-              "\x00\x00\x00\x00" // cache path count
-              "\x00\x00\x00\x01" // event filter count
+              NUM64("\x11") // full size
+              NUM32("\x00") // cache path count
+              NUM32("\x01") // event filter count
               "\x00" // event filter[0]
               "\x00" // override event filter[0]
               "\x00\x00\x00\x00\x00\x00\x00"), // block size
          "Area too small when reading size of 'block size'" },
        /* first block size is 0, which is too small */
        { DATA("DOVECOT-CONFIG\t1.0\n"
-              "\x00\x00\x00\x00\x00\x00\x00\x12" // full size
-              "\x00\x00\x00\x00" // cache path count
-              "\x00\x00\x00\x01" // event filter count
+              NUM64("\x12") // full size
+              NUM32("\x00") // cache path count
+              NUM32("\x01") // event filter count
               "\x00" // event filter[0]
               "\x00" // override event filter[0]
-              "\x00\x00\x00\x00\x00\x00\x00\x00"), // block size
+              NUM64("\x00")), // block size
          "'block name' points outside area" },
        /* first block size is 1, but full file size is too small */
        { DATA("DOVECOT-CONFIG\t1.0\n"
-              "\x00\x00\x00\x00\x00\x00\x00\x12" // full size
-              "\x00\x00\x00\x00" // cache path count
-              "\x00\x00\x00\x01" // event filter count
+              NUM64("\x12") // full size
+              NUM32("\x00") // cache path count
+              NUM32("\x01") // event filter count
               "\x00" // event filter[0]
               "\x00" // override event filter[0]
-              "\x00\x00\x00\x00\x00\x00\x00\x01"), // block size
+              NUM64("\x01")), // block size
          "'block size' points outside are" },
        /* block name is not NUL-terminated */
        { DATA("DOVECOT-CONFIG\t1.0\n"
-              "\x00\x00\x00\x00\x00\x00\x00\x14" // full size
-              "\x00\x00\x00\x00" // cache path count
-              "\x00\x00\x00\x01" // event filter count
+              NUM64("\x14") // full size
+              NUM32("\x00") // cache path count
+              NUM32("\x01") // event filter count
               "\x00" // event filter[0]
               "\x00" // override event filter[0]
-              "\x00\x00\x00\x00\x00\x00\x00\x01" // block size
+              NUM64("\x01") // block size
               "N"
               "\x00"), // trailing garbage so we can have NUL
          "Settings block doesn't end with NUL at offset" },
 
        /* settings count is truncated */
        { DATA("DOVECOT-CONFIG\t1.0\n"
-              "\x00\x00\x00\x00\x00\x00\x00\x17" // full size
-              "\x00\x00\x00\x00" // cache path count
-              "\x00\x00\x00\x01" // event filter count
+              NUM64("\x17") // full size
+              NUM32("\x00") // cache path count
+              NUM32("\x01") // event filter count
               "\x00" // event filter[0]
               "\x00" // override event filter[0]
-              "\x00\x00\x00\x00\x00\x00\x00\x05" // block size
+              NUM64("\x05") // block size
               "N\x00" // block name
               "\x00\x00\x00"),
          "Area too small when reading uint of 'settings count'" },
 
        /* settings keys are truncated */
        { DATA("DOVECOT-CONFIG\t1.0\n"
-              "\x00\x00\x00\x00\x00\x00\x00\x18" // full size
-              "\x00\x00\x00\x00" // cache path count
-              "\x00\x00\x00\x01" // event filter count
+              NUM64("\x18") // full size
+              NUM32("\x00") // cache path count
+              NUM32("\x01") // event filter count
               "\x00" // event filter[0]
               "\x00" // override event filter[0]
-              "\x00\x00\x00\x00\x00\x00\x00\x06" // block size
+              NUM64("\x06") // block size
               "N\x00" // block name
-              "\x00\x00\x01\x00"), // settings count
+              NUM32("\x01")), // settings count
          "'setting key' points outside area" },
 
        /* filter count is truncated */
        { DATA("DOVECOT-CONFIG\t1.0\n"
-              "\x00\x00\x00\x00\x00\x00\x00\x1D" // full size
-              "\x00\x00\x00\x00" // cache path count
-              "\x00\x00\x00\x01" // event filter count
+              NUM64("\x1D") // full size
+              NUM32("\x00") // cache path count
+              NUM32("\x01") // event filter count
               "\x00" // event filter[0]
               "\x00" // override event filter[0]
-              "\x00\x00\x00\x00\x00\x00\x00\x0B" // block size
+              NUM64("\x0B") // block size
               "N\x00" // block name
-              "\x00\x00\x00\x01" // settings count
+              NUM32("\x01") // settings count
               "K\x00" // setting[0] key
               "\x00\x00\x00"), // filter count
          "Area too small when reading uint of 'filter count'" },
 
        /* filter settings size is truncated */
        { DATA("DOVECOT-CONFIG\t1.0\n"
-              "\x00\x00\x00\x00\x00\x00\x00\x25" // full size
-              "\x00\x00\x00\x00" // cache path count
-              "\x00\x00\x00\x01" // event filter count
+              NUM64("\x25") // full size
+              NUM32("\x00") // cache path count
+              NUM32("\x01") // event filter count
               "\x00" // event filter[0]
               "\x00" // override event filter[0]
-              "\x00\x00\x00\x00\x00\x00\x00\x12" // block size
+              NUM64("\x12") // block size
               "N\x00" // block name
-              "\x00\x00\x00\x01" // settings count
+              NUM32("\x01") // settings count
               "K\x00" // setting[0] key
-              "\x00\x00\x00\x01" // filter count
+              NUM32("\x01") // filter count
               "\x00\x00\x00\x00\x00\x00\x00"), // filter settings size
          "Area too small when reading size of 'filter settings size'" },
 
        /* filter settings is truncated */
        { DATA("DOVECOT-CONFIG\t1.0\n"
-              "\x00\x00\x00\x00\x00\x00\x00\x26" // full size
-              "\x00\x00\x00\x00" // cache path count
-              "\x00\x00\x00\x01" // event filter count
+              NUM64("\x26") // full size
+              NUM32("\x00") // cache path count
+              NUM32("\x01") // event filter count
               "\x00" // event filter[0]
               "\x00" // override event filter[0]
-              "\x00\x00\x00\x00\x00\x00\x00\x14" // block size
+              NUM64("\x14") // block size
               "N\x00" // block name
-              "\x00\x00\x00\x01" // settings count
+              NUM32("\x01") // settings count
               "K\x00" // setting[0] key
-              "\x00\x00\x00\x01" // filter count
-              "\x00\x00\x00\x00\x00\x00\x10\x00"), // filter settings size
+              NUM32("\x01") // filter count
+              NUM64("\x10")), // filter settings size
          "'filter settings size' points outside area" },
        /* filter error is missing */
        { DATA("DOVECOT-CONFIG\t1.0\n"
-              "\x00\x00\x00\x00\x00\x00\x00\x33" // full size
-              "\x00\x00\x00\x00" // cache path count
-              "\x00\x00\x00\x01" // event filter count
+              NUM64("\x33") // full size
+              NUM32("\x00") // cache path count
+              NUM32("\x01") // event filter count
               "\x00" // event filter[0]
               "\x00" // override event filter[0]
-              "\x00\x00\x00\x00\x00\x00\x00\x21" // block size
+              NUM64("\x21") // block size
               "N\x00" // block name
-              "\x00\x00\x00\x01" // settings count
+              NUM32("\x01") // settings count
               "K\x00" // setting[0] key
-              "\x00\x00\x00\x01" // filter count
-              "\x00\x00\x00\x00\x00\x00\x00\x00" // filter settings size
-              "\x00\x00\x00\x00" // event filter index
-              "\x00\x00\x00\x00\x00\x00\x00\x00" // filter settings offset
+              NUM32("\x01") // filter count
+              NUM64("\x00") // filter settings size
+              NUM32("\x00") // event filter index
+              NUM64("\x00") // filter settings offset
               "\x00"), // safety NUL
          "'filter error string' points outside area" },
        /* filter error is not NUL-terminated */
        { DATA("DOVECOT-CONFIG\t1.0\n"
-              "\x00\x00\x00\x00\x00\x00\x00\x41" // full size
-              "\x00\x00\x00\x00" // cache path count
-              "\x00\x00\x00\x01" // event filter count
+              NUM64("\x41") // full size
+              NUM32("\x00") // cache path count
+              NUM32("\x01") // event filter count
               "\x00" // event filter[0]
               "\x00" // override event filter[0]
-              "\x00\x00\x00\x00\x00\x00\x00\x2F" // block size
+              NUM64("\x2F") // block size
               "master_service\x00" // block name
-              "\x00\x00\x00\x01" // settings count
+              NUM32("\x01") // settings count
               "K\x00" // setting[0] key
-              "\x00\x00\x00\x01" // filter count
-              "\x00\x00\x00\x00\x00\x00\x00\x01" // filter settings size
+              NUM32("\x01") // filter count
+              NUM64("\x01") // filter settings size
               "E" // filter error string
-              "\x00\x00\x00\x00" // event filter index
-              "\x00\x00\x00\x00\x00\x00\x00\x00" // filter settings offset
+              NUM32("\x00") // event filter index
+              NUM64("\x00") // filter settings offset
               "\x00"), // safety NUL
          "'filter error string' points outside area" },
        /* include group count is truncated */
        { DATA("DOVECOT-CONFIG\t1.0\n"
-              "\x00\x00\x00\x00\x00\x00\x00\x44" // full size
-              "\x00\x00\x00\x00" // cache path count
-              "\x00\x00\x00\x01" // event filter count
+              NUM64("\x44") // full size
+              NUM32("\x00") // cache path count
+              NUM32("\x01") // event filter count
               "\x00" // event filter[0]
               "\x00" // override event filter[0]
-              "\x00\x00\x00\x00\x00\x00\x00\x32" // block size
+              NUM64("\x32") // block size
               "master_service\x00" // block name
-              "\x00\x00\x00\x01" // settings count
+              NUM32("\x01") // settings count
               "K\x00" // setting[0] key
-              "\x00\x00\x00\x01" // filter count
-              "\x00\x00\x00\x00\x00\x00\x00\x04" // filter settings size
+              NUM32("\x01") // filter count
+              NUM64("\x04") // filter settings size
               "\x00" // filter error string
               "\x00\x00\x00" // include group count
-              "\x00\x00\x00\x00" // event filter index
-              "\x00\x00\x00\x00\x00\x00\x00\x00" // filter settings offset
+              NUM32("\x00") // event filter index
+              NUM64("\x00") // filter settings offset
               "\x00"), // safety NUL
          "Area too small when reading uint of 'include group count'" },
        /* include group count is too large */
        { DATA("DOVECOT-CONFIG\t1.0\n"
-              "\x00\x00\x00\x00\x00\x00\x00\x45" // full size
-              "\x00\x00\x00\x00" // cache path count
-              "\x00\x00\x00\x01" // event filter count
+              NUM64("\x45") // full size
+              NUM32("\x00") // cache path count
+              NUM32("\x01") // event filter count
               "\x00" // event filter[0]
               "\x00" // override event filter[0]
-              "\x00\x00\x00\x00\x00\x00\x00\x33" // block size
+              NUM64("\x33") // block size
               "master_service\x00" // block name
-              "\x00\x00\x00\x01" // settings count
+              NUM32("\x01") // settings count
               "K\x00" // setting[0] key
-              "\x00\x00\x00\x01" // filter count
-              "\x00\x00\x00\x00\x00\x00\x00\x05" // filter settings size
+              NUM32("\x01") // filter count
+              NUM64("\x05") // filter settings size
               "\x00" // filter error string
-              "\x00\x00\x00\x01" // include group count
-              "\x00\x00\x00\x00" // event filter index
-              "\x00\x00\x00\x00\x00\x00\x00\x00" // filter settings offset
+              NUM32("\x01") // include group count
+              NUM32("\x00") // event filter index
+              NUM64("\x00") // filter settings offset
               "\x00"), // safety NUL
          "'group label string' points outside area" },
        /* group label not NUL-terminated */
        { DATA("DOVECOT-CONFIG\t1.0\n"
-              "\x00\x00\x00\x00\x00\x00\x00\x46" // full size
-              "\x00\x00\x00\x00" // cache path count
-              "\x00\x00\x00\x01" // event filter count
+              NUM64("\x46") // full size
+              NUM32("\x00") // cache path count
+              NUM32("\x01") // event filter count
               "\x00" // event filter[0]
               "\x00" // override event filter[0]
-              "\x00\x00\x00\x00\x00\x00\x00\x34" // block size
+              NUM64("\x34") // block size
               "master_service\x00" // block name
-              "\x00\x00\x00\x01" // settings count
+              NUM32("\x01") // settings count
               "K\x00" // setting[0] key
-              "\x00\x00\x00\x01" // filter count
-              "\x00\x00\x00\x00\x00\x00\x00\x06" // filter settings size
+              NUM32("\x01") // filter count
+              NUM64("\x06") // filter settings size
               "\x00" // filter error string
-              "\x00\x00\x00\x01" // include group count
+              NUM32("\x01") // include group count
               "G" // group label
-              "\x00\x00\x00\x00" // event filter index
-              "\x00\x00\x00\x00\x00\x00\x00\x00" // filter settings offset
+              NUM32("\x00") // event filter index
+              NUM64("\x00") // filter settings offset
               "\x00"), // safety NUL
          "'group label string' points outside area" },
        /* group name not NUL-terminated */
        { DATA("DOVECOT-CONFIG\t1.0\n"
-              "\x00\x00\x00\x00\x00\x00\x00\x48" // full size
-              "\x00\x00\x00\x00" // cache path count
-              "\x00\x00\x00\x01" // event filter count
+              NUM64("\x48") // full size
+              NUM32("\x00") // cache path count
+              NUM32("\x01") // event filter count
               "\x00" // event filter[0]
               "\x00" // override event filter[0]
-              "\x00\x00\x00\x00\x00\x00\x00\x36" // block size
+              NUM64("\x36") // block size
               "master_service\x00" // block name
-              "\x00\x00\x00\x01" // settings count
+              NUM32("\x01") // settings count
               "K\x00" // setting[0] key
-              "\x00\x00\x00\x01" // filter count
-              "\x00\x00\x00\x00\x00\x00\x00\x08" // filter settings size
+              NUM32("\x01") // filter count
+              NUM64("\x08") // filter settings size
               "\x00" // filter error string
-              "\x00\x00\x00\x01" // include group count
+              NUM32("\x01") // include group count
               "G\x00" // group label
               "N" // group name
-              "\x00\x00\x00\x00" // event filter index
-              "\x00\x00\x00\x00\x00\x00\x00\x00" // filter settings offset
+              NUM32("\x00") // event filter index
+              NUM64("\x00") // filter settings offset
               "\x00"), // safety NUL
          "'group name string' points outside area" },
        /* invalid filter string */
        { DATA("DOVECOT-CONFIG\t1.0\n"
-              "\x00\x00\x00\x00\x00\x00\x00\x3A" // full size
-              "\x00\x00\x00\x00" // cache path count
-              "\x00\x00\x00\x01" // event filter count
+              NUM64("\x3A") // full size
+              NUM32("\x00") // cache path count
+              NUM32("\x01") // event filter count
               "F\x00" // event filter[0]
               "F\x00" // override event filter[0]
-              "\x00\x00\x00\x00\x00\x00\x00\x26" // block size
+              NUM64("\x26") // block size
               "N\x00" // block name
-              "\x00\x00\x00\x01" // settings count
+              NUM32("\x01") // settings count
               "K\x00" // setting[0] key
-              "\x00\x00\x00\x01" // filter count
-              "\x00\x00\x00\x00\x00\x00\x00\x05" // filter settings size
+              NUM32("\x01") // filter count
+              NUM64("\x05") // filter settings size
               "\x00" // filter error string
-              "\x00\x00\x00\x00" // include group count
-              "\x00\x00\x00\x00" // event filter index
-              "\x00\x00\x00\x00\x00\x00\x00\x00" // filter settings offset
+              NUM32("\x00") // include group count
+              NUM32("\x00") // event filter index
+              NUM64("\x00") // filter settings offset
               "\x00"), // safety NUL
          "Received invalid filter 'F' at index 0: event filter: syntax error" },
 
        /* Duplicate block name */
        { DATA("DOVECOT-CONFIG\t1.0\n"
-              "\x00\x00\x00\x00\x00\x00\x00\x42" // full size
-              "\x00\x00\x00\x00" // cache path count
-              "\x00\x00\x00\x01" // event filter count
+              NUM64("\x42") // full size
+              NUM32("\x00") // cache path count
+              NUM32("\x01") // event filter count
               "\x00" // event filter[0]
               "\x00" // override event filter[0]
-              "\x00\x00\x00\x00\x00\x00\x00\x26" // block size
+              NUM64("\x26") // block size
               "N\x00" // block name
-              "\x00\x00\x00\x01" // settings count
+              NUM32("\x01") // settings count
               "K\x00" // setting[0] key
-              "\x00\x00\x00\x01" // filter count
-              "\x00\x00\x00\x00\x00\x00\x00\x05" // filter settings size
+              NUM32("\x01") // filter count
+              NUM64("\x05") // filter settings size
               "\x00" // filter error string
-              "\x00\x00\x00\x00" // include group count
-              "\x00\x00\x00\x00" // event filter index
-              "\x00\x00\x00\x00\x00\x00\x00\x00" // filter settings offset
+              NUM32("\x00") // include group count
+              NUM32("\x00") // event filter index
+              NUM64("\x00") // filter settings offset
               "\x00" // safety NUL
-              "\x00\x00\x00\x00\x00\x00\x00\x02" // 2nd block size
+              NUM64("\x02") // 2nd block size
               "N\x00"), // 2nd block name
          "Duplicate block name 'N'" },
 };
index fcf90c08ec4f692dd5e999a292aa51b6dfcf0930..80526dc6ae5b1a8e3f70725a418646766e629446 100644 (file)
@@ -224,7 +224,8 @@ settings_block_read_uint64(struct settings_mmap *mmap,
                        *offset, end_offset, mmap->mmap_size);
                return -1;
        }
-       *num_r = be64_to_cpu_unaligned(CONST_PTR_OFFSET(mmap->mmap_base, *offset));
+       memcpy(num_r, CONST_PTR_OFFSET(mmap->mmap_base, *offset),
+              sizeof(*num_r));
        *offset += sizeof(*num_r);
        return 0;
 }
@@ -242,7 +243,8 @@ settings_block_read_uint32(struct settings_mmap *mmap,
                        *offset, end_offset, mmap->mmap_size);
                return -1;
        }
-       *num_r = be32_to_cpu_unaligned(CONST_PTR_OFFSET(mmap->mmap_base, *offset));
+       memcpy(num_r, CONST_PTR_OFFSET(mmap->mmap_base, *offset),
+              sizeof(*num_r));
        *offset += sizeof(*num_r);
        return 0;
 }
@@ -260,7 +262,8 @@ settings_block_read_size(struct settings_mmap *mmap,
                        *offset, end_offset, mmap->mmap_size);
                return -1;
        }
-       *size_r = be64_to_cpu_unaligned(CONST_PTR_OFFSET(mmap->mmap_base, *offset));
+       memcpy(size_r, CONST_PTR_OFFSET(mmap->mmap_base, *offset),
+              sizeof(*size_r));
        if (*size_r > end_offset - *offset - sizeof(*size_r)) {
                *error_r = t_strdup_printf(
                        "'%s' points outside area "
@@ -697,8 +700,9 @@ settings_mmap_parse(struct settings_mmap *mmap, const char *service_name,
 
        /* <settings full size> */
        size_t full_size_offset = eol - mmap_base + 1;
-       uint64_t settings_full_size =
-               be64_to_cpu_unaligned(mmap_base + full_size_offset);
+       uint64_t settings_full_size;
+       memcpy(&settings_full_size, mmap_base + full_size_offset,
+              sizeof(settings_full_size));
        if (full_size_offset + sizeof(settings_full_size) +
            settings_full_size != mmap_size) {
                *error_r = t_strdup_printf("Full size mismatch: "
@@ -958,8 +962,9 @@ settings_mmap_apply_blob(struct settings_apply_ctx *ctx,
        while (offset < end_offset) {
                /* We already checked that settings blob ends with NUL, so
                   strlen() can be used safely. */
-               uint32_t key_idx = be32_to_cpu_unaligned(
-                       CONST_PTR_OFFSET(mmap->mmap_base, offset));
+               uint32_t key_idx;
+               memcpy(&key_idx, CONST_PTR_OFFSET(mmap->mmap_base, offset),
+                      sizeof(key_idx));
                if (key_idx >= block->settings_count) {
                        *error_r = t_strdup_printf(
                                "Settings key index too high (%u >= %u)",
@@ -1086,10 +1091,13 @@ settings_mmap_get_filter_idx(struct settings_mmap *mmap,
                             uint32_t filter_idx, uint32_t *event_filter_idx_r,
                             const char **error_r)
 {
-       uint32_t event_filter_idx = be32_to_cpu_unaligned(
-               CONST_PTR_OFFSET(mmap->mmap_base,
-                                block->filter_indexes_start_offset +
-                                sizeof(uint32_t) * filter_idx));
+       uint32_t event_filter_idx;
+
+       memcpy(&event_filter_idx,
+              CONST_PTR_OFFSET(mmap->mmap_base,
+                               block->filter_indexes_start_offset +
+                               sizeof(uint32_t) * filter_idx),
+              sizeof(event_filter_idx));
        if (event_filter_idx >= mmap->event_filters_count) {
                *error_r = t_strdup_printf("event filter idx %u >= %u",
                        event_filter_idx, mmap->event_filters_count);
@@ -1107,12 +1115,15 @@ static int settings_mmap_apply_filter(struct settings_apply_ctx *ctx,
                                      const char **error_r)
 {
        struct settings_mmap *mmap = ctx->instance->mmap;
-       uint64_t filter_offset = be64_to_cpu_unaligned(
-               CONST_PTR_OFFSET(mmap->mmap_base,
-                                block->filter_offsets_start_offset +
-                                sizeof(uint64_t) * filter_idx));
-       uint64_t filter_set_size = be64_to_cpu_unaligned(
-               CONST_PTR_OFFSET(mmap->mmap_base, filter_offset));
+       uint64_t filter_offset, filter_set_size;
+       memcpy(&filter_offset,
+              CONST_PTR_OFFSET(mmap->mmap_base,
+                               block->filter_offsets_start_offset +
+                               sizeof(uint64_t) * filter_idx),
+              sizeof(filter_offset));
+       memcpy(&filter_set_size,
+              CONST_PTR_OFFSET(mmap->mmap_base, filter_offset),
+              sizeof(filter_set_size));
        filter_offset += sizeof(filter_set_size);
        uint64_t filter_end_offset = filter_offset + filter_set_size;
 
@@ -1124,8 +1135,9 @@ static int settings_mmap_apply_filter(struct settings_apply_ctx *ctx,
        }
        filter_offset += strlen(filter_error) + 1;
 
-       uint32_t include_count = be32_to_cpu_unaligned(
-               CONST_PTR_OFFSET(mmap->mmap_base, filter_offset));
+       uint32_t include_count;
+       memcpy(&include_count, CONST_PTR_OFFSET(mmap->mmap_base, filter_offset),
+              sizeof(include_count));
        filter_offset += sizeof(include_count);
 
        if (ctx->filter_name != NULL && !ctx->seen_filter &&