]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
config, lib-settings: Access filter index/offset arrays directly via mmap
authorTimo Sirainen <timo.sirainen@open-xchange.com>
Wed, 26 Feb 2025 10:43:15 +0000 (12:43 +0200)
committertimo.sirainen <timo.sirainen@open-xchange.com>
Mon, 12 May 2025 15:51:47 +0000 (15:51 +0000)
Add 64bit alignment to the start offset to make this safe.

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

index 26d9a906f40fd82f09a48a2b3ffb986385c25dea..fe2171ea9271763010a1e63825ab21e1aba765de 100644 (file)
          <32bit: key index number>
         [+|$ <strlist/boollist key>]
         <NUL-terminated string: value>
-     Repeat for "filter count":
-       <32bit: event filter string index number>
+
+     <0..7 bytes for 64bit alignment>
      Repeat for "filter count":
        <64bit: filter settings offset>
+     Repeat for "filter count":
+       <32bit: event filter string index number>
      <trailing safety NUL>
 
    The order of filters is important in the output. lib-settings applies the
@@ -887,12 +889,18 @@ int config_dump_full(struct config_parsed *config,
                        break;
 
                if (dest != CONFIG_DUMP_FULL_DEST_STDOUT) {
-                       o_stream_nsend(output, ctx.filter_indexes_32,
-                                      sizeof(ctx.filter_indexes_32[0]) *
-                                      ctx.filter_output_count);
+                       /* use 64bit alignment */
+                       if (output->offset % sizeof(uint64_t) != 0) {
+                               uint64_t align = 0;
+                               o_stream_nsend(output, &align, sizeof(uint64_t) -
+                                              output->offset % sizeof(uint64_t));
+                       }
                        o_stream_nsend(output, ctx.filter_offsets_64,
                                       sizeof(ctx.filter_offsets_64[0]) *
                                       ctx.filter_output_count);
+                       o_stream_nsend(output, ctx.filter_indexes_32,
+                                      sizeof(ctx.filter_indexes_32[0]) *
+                                      ctx.filter_output_count);
                        /* safety NUL at the end of the block */
                        o_stream_nsend(output, "", 1);
                }
index 7ebb356a652705e05d924d3296c8ae1e034593fe..d3a614fd145b44d5c79f85e5a43fd4fc6567a9c3 100644 (file)
@@ -294,19 +294,20 @@ static const struct {
               NUM64("\x05") // filter settings size
               "\x00" // filter error string
               NUM32("\x00") // include group count
-              NUM32("\x00") // event filter index
-              NUM64("\x00") // filter settings offset
+              // 64bit padding
+              NUM64("\x00") // filter[0] settings offset
+              NUM32("\x00") // filter[0] event filter index
               "\x00"), // safety NUL
          "Received invalid filter 'F' at index 0: event filter: syntax error" },
 
        /* Duplicate block name */
        { DATA("DOVECOT-CONFIG\t1.0\n"
-              NUM64("\x42") // full size
+              NUM64("\x44") // full size
               NUM32("\x00") // cache path count
               NUM32("\x01") // event filter count
               "\x00" // event filter[0]
               "\x00" // override event filter[0]
-              NUM64("\x26") // block size
+              NUM64("\x28") // block size
               "N\x00" // block name
               NUM32("\x01") // settings count
               "K\x00" // setting[0] key
@@ -314,8 +315,9 @@ static const struct {
               NUM64("\x05") // filter settings size
               "\x00" // filter error string
               NUM32("\x00") // include group count
-              NUM32("\x00") // event filter index
-              NUM64("\x00") // filter settings offset
+              "\x00\x00" // 64bit padding
+              NUM64("\x00") // filter[0] settings offset
+              NUM32("\x00") // filter[0] event filter index
               "\x00" // safety NUL
               NUM64("\x02") // 2nd block size
               "N\x00"), // 2nd block name
index 80526dc6ae5b1a8e3f70725a418646766e629446..3f75cea7d652c1699d91c058caa63bf29083b537 100644 (file)
@@ -98,8 +98,8 @@ struct settings_mmap_block {
        size_t block_end_offset;
 
        uint32_t filter_count;
-       size_t filter_indexes_start_offset;
-       size_t filter_offsets_start_offset;
+       const uint64_t *filter_offsets;
+       const uint32_t *filter_indexes;
 
        uint32_t settings_count;
        size_t settings_keys_offset;
@@ -647,10 +647,12 @@ settings_block_read(struct settings_mmap *mmap, size_t *_offset,
                offset += filter_settings_size;
        }
 
-       block->filter_indexes_start_offset = offset;
-       offset += sizeof(uint32_t) * block->filter_count;
-       block->filter_offsets_start_offset = offset;
+       if (offset % sizeof(uint64_t) != 0)
+               offset += sizeof(uint64_t) - offset % sizeof(uint64_t);
+       block->filter_offsets = CONST_PTR_OFFSET(mmap->mmap_base, offset);
        offset += sizeof(uint64_t) * block->filter_count;
+       block->filter_indexes = CONST_PTR_OFFSET(mmap->mmap_base, offset);
+       offset += sizeof(uint32_t) * block->filter_count;
        offset++; /* safety NUL */
 
        if (offset != block_end_offset) {
@@ -1091,19 +1093,12 @@ 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;
-
-       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) {
+       *event_filter_idx_r = block->filter_indexes[filter_idx];
+       if (*event_filter_idx_r >= mmap->event_filters_count) {
                *error_r = t_strdup_printf("event filter idx %u >= %u",
-                       event_filter_idx, mmap->event_filters_count);
+                       *event_filter_idx_r, mmap->event_filters_count);
                return -1;
        }
-       *event_filter_idx_r = event_filter_idx;
        return 0;
 }
 
@@ -1116,11 +1111,8 @@ static int settings_mmap_apply_filter(struct settings_apply_ctx *ctx,
 {
        struct settings_mmap *mmap = ctx->instance->mmap;
        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));
+
+       filter_offset = block->filter_offsets[filter_idx];
        memcpy(&filter_set_size,
               CONST_PTR_OFFSET(mmap->mmap_base, filter_offset),
               sizeof(filter_set_size));