From: Timo Sirainen Date: Wed, 26 Feb 2025 10:43:15 +0000 (+0200) Subject: config, lib-settings: Access filter index/offset arrays directly via mmap X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=855215a74641133bfec1884a4273327cf7ccf09a;p=thirdparty%2Fdovecot%2Fcore.git config, lib-settings: Access filter index/offset arrays directly via mmap Add 64bit alignment to the start offset to make this safe. --- diff --git a/src/config/config-dump-full.c b/src/config/config-dump-full.c index 26d9a906f4..fe2171ea92 100644 --- a/src/config/config-dump-full.c +++ b/src/config/config-dump-full.c @@ -63,10 +63,12 @@ <32bit: key index number> [+|$ ] - 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> 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); } diff --git a/src/lib-master/test-master-service-settings.c b/src/lib-master/test-master-service-settings.c index 7ebb356a65..d3a614fd14 100644 --- a/src/lib-master/test-master-service-settings.c +++ b/src/lib-master/test-master-service-settings.c @@ -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 diff --git a/src/lib-settings/settings.c b/src/lib-settings/settings.c index 80526dc6ae..3f75cea7d6 100644 --- a/src/lib-settings/settings.c +++ b/src/lib-settings/settings.c @@ -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));