From f6e23af1c5994363f8bb3bfd901f31c1cc6709ef Mon Sep 17 00:00:00 2001 From: Stephan Bosch <stephan@rename-it.nl> Date: Sun, 7 Sep 2008 15:41:59 +0200 Subject: [PATCH] Variables: made sure broken/malicious binary cannot allocate variable storage of arbitrary size. --- TODO | 1 - .../plugins/include/ext-include-common.c | 2 +- .../plugins/variables/ext-variables-common.c | 33 ++++++++----------- .../variables/ext-variables-operands.c | 4 +-- .../plugins/variables/sieve-ext-variables.h | 5 ++- 5 files changed, 19 insertions(+), 26 deletions(-) diff --git a/TODO b/TODO index 7dbf0bd30..1756bdf69 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 a35b31ead..c9224c0ef 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 b6b22e4f6..9343f417a 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 4799523b6..2a123a90e 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 f46f697de..b85b21056 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); -- GitLab