diff --git a/TODO b/TODO index 7dbf0bd300e861ff1730d30dca030ab498009c58..1756bdf69c1af220668408e08f475aa12b61ae75 100644 --- a/TODO +++ b/TODO @@ -5,7 +5,6 @@ Next (in order of descending priority/precedence): * Fix security issues: - Impose limitations on the imapflags extension regarding the number of set flags and the length of each flag name. - - Malicious/Broken binary can allocate large variable storage * Finish the test suite for the base functionality * Improve debugging and error handling: - Improve byte code dumping and trace functionality to be a little more diff --git a/src/lib-sieve/plugins/include/ext-include-common.c b/src/lib-sieve/plugins/include/ext-include-common.c index a35b31eadad8288443c106e20f587a9cce8be87c..c9224c0ef5188f6ebb590984538d8ba03869323f 100644 --- a/src/lib-sieve/plugins/include/ext-include-common.c +++ b/src/lib-sieve/plugins/include/ext-include-common.c @@ -233,7 +233,7 @@ static void ext_include_runtime_init if ( ctx->parent == NULL ) { ctx->global_variables = sieve_variable_storage_create - (ctx->pool, ext_include_binary_get_global_scope(renv->sbin)); + (ctx->pool, ext_include_binary_get_global_scope(renv->sbin), 0); } else { ctx->global_variables = ctx->parent->global_variables; } diff --git a/src/lib-sieve/plugins/variables/ext-variables-common.c b/src/lib-sieve/plugins/variables/ext-variables-common.c index b6b22e4f676736c47c373624ce50b55f3b783602..9343f417ab42075618ac209ccbd8c40d17da7172 100644 --- a/src/lib-sieve/plugins/variables/ext-variables-common.c +++ b/src/lib-sieve/plugins/variables/ext-variables-common.c @@ -198,17 +198,23 @@ struct sieve_variable * const *sieve_variable_scope_get_variables struct sieve_variable_storage { pool_t pool; struct sieve_variable_scope *scope; + unsigned int max_size; ARRAY_DEFINE(var_values, string_t *); }; struct sieve_variable_storage *sieve_variable_storage_create -(pool_t pool, struct sieve_variable_scope *scope) +(pool_t pool, struct sieve_variable_scope *scope, unsigned int max_size) { struct sieve_variable_storage *storage; storage = p_new(pool, struct sieve_variable_storage, 1); storage->pool = pool; storage->scope = scope; + + if ( scope != NULL ) + storage->max_size = sieve_variable_scope_size(scope); + else + storage->max_size = max_size; p_array_init(&storage->var_values, pool, 4); @@ -220,7 +226,7 @@ static inline bool sieve_variable_valid { if ( storage->scope == NULL ) return TRUE; - return ( index < array_count(&storage->scope->variable_index) ); + return ( index < storage->max_size ); } bool sieve_variable_get_identifier @@ -469,13 +475,14 @@ struct ext_variables_interpreter_context { }; static struct ext_variables_interpreter_context * -ext_variables_interpreter_context_create(struct sieve_interpreter *interp) +ext_variables_interpreter_context_create +(struct sieve_interpreter *interp, unsigned int max_size) { pool_t pool = sieve_interpreter_pool(interp); struct ext_variables_interpreter_context *ctx; ctx = p_new(pool, struct ext_variables_interpreter_context, 1); - ctx->local_storage = sieve_variable_storage_create(pool, NULL); + ctx->local_storage = sieve_variable_storage_create(pool, NULL, max_size); p_array_init(&ctx->ext_storages, pool, sieve_extensions_get_count()); sieve_interpreter_extension_set_context @@ -512,7 +519,7 @@ bool ext_variables_interpreter_load *address = pc + end_offset; /* Create our context */ - ctx = ext_variables_interpreter_context_create(renv->interp); + ctx = ext_variables_interpreter_context_create(renv->interp, scope_size); /* Enable support for match values */ (void) sieve_match_values_set_enabled(renv->interp, TRUE); @@ -528,8 +535,7 @@ ext_variables_interpreter_context_get(struct sieve_interpreter *interp) } struct sieve_variable_storage *sieve_ext_variables_get_storage -(struct sieve_interpreter *interp, const struct sieve_extension *ext, - bool create) +(struct sieve_interpreter *interp, const struct sieve_extension *ext) { struct ext_variables_interpreter_context *ctx = ext_variables_interpreter_context_get(interp); @@ -546,19 +552,8 @@ struct sieve_variable_storage *sieve_ext_variables_get_storage storage = array_idx(&ctx->ext_storages, ext_id); } - if ( storage == NULL || *storage == NULL ) { - if ( create ) { - pool_t pool = sieve_interpreter_pool(interp); - struct sieve_variable_storage *strg = - sieve_variable_storage_create(pool, NULL); - - array_idx_set(&ctx->ext_storages, (unsigned int) ext_id, &strg); - - return strg; - } - + if ( storage == NULL || *storage == NULL ) return NULL; - } return *storage; } diff --git a/src/lib-sieve/plugins/variables/ext-variables-operands.c b/src/lib-sieve/plugins/variables/ext-variables-operands.c index 4799523b6a376d75b3ceb3977fe44507cf866473..2a123a90e9f095e84c8a222913e32b5184b09218 100644 --- a/src/lib-sieve/plugins/variables/ext-variables-operands.c +++ b/src/lib-sieve/plugins/variables/ext-variables-operands.c @@ -91,7 +91,7 @@ static bool opr_variable_read_value if ( !sieve_binary_read_extension(renv->sbin, address, &code, &ext) ) return FALSE; - storage = sieve_ext_variables_get_storage(renv->interp, ext, FALSE); + storage = sieve_ext_variables_get_storage(renv->interp, ext); if ( storage == NULL ) return FALSE; @@ -127,7 +127,7 @@ bool sieve_variable_operand_read_data if ( !sieve_binary_read_extension(renv->sbin, address, &code, &ext) ) return FALSE; - *storage = sieve_ext_variables_get_storage(renv->interp, ext, FALSE); + *storage = sieve_ext_variables_get_storage(renv->interp, ext); if ( *storage == NULL ) return FALSE; diff --git a/src/lib-sieve/plugins/variables/sieve-ext-variables.h b/src/lib-sieve/plugins/variables/sieve-ext-variables.h index f46f697defe165e80effa69068b178fdde4e3682..b85b210568374758f7cdc5ba22e3934c6d586f61 100644 --- a/src/lib-sieve/plugins/variables/sieve-ext-variables.h +++ b/src/lib-sieve/plugins/variables/sieve-ext-variables.h @@ -74,7 +74,7 @@ struct sieve_variable * const *sieve_variable_scope_get_variables struct sieve_variable_storage; struct sieve_variable_storage *sieve_variable_storage_create - (pool_t pool, struct sieve_variable_scope *scope); + (pool_t pool, struct sieve_variable_scope *scope, unsigned int max_size); bool sieve_variable_get (struct sieve_variable_storage *storage, unsigned int index, string_t **value); @@ -98,8 +98,7 @@ struct sieve_variable_scope *sieve_ext_variables_get_main_scope (struct sieve_validator *validator); struct sieve_variable_storage *sieve_ext_variables_get_storage - (struct sieve_interpreter *interp, const struct sieve_extension *ext, - bool create); + (struct sieve_interpreter *interp, const struct sieve_extension *ext); void sieve_ext_variables_set_storage (struct sieve_interpreter *interp, struct sieve_variable_storage *storage, const struct sieve_extension *ext);