dovecot-2.2-pigeonhole: lib-sieve: mime/foreverypart: Implemente...
pigeonhole at rename-it.nl
pigeonhole at rename-it.nl
Sun Nov 29 12:00:43 UTC 2015
details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/5607f866fd94
changeset: 2144:5607f866fd94
user: Stephan Bosch <stephan at rename-it.nl>
date: Sun Nov 29 13:00:38 2015 +0100
description:
lib-sieve: mime/foreverypart: Implemented loop nesting limit.
diffstat:
src/lib-sieve/plugins/mime/cmd-foreverypart.c | 43 +++++++++++++++++++++++---
src/lib-sieve/sieve-interpreter.c | 20 ++++++++++--
src/lib-sieve/sieve-interpreter.h | 5 +-
src/lib-sieve/sieve-limits.h | 2 +
tests/extensions/mime/errors.svtest | 10 ++++++
tests/extensions/mime/errors/limits.sieve | 13 ++++++++
6 files changed, 82 insertions(+), 11 deletions(-)
diffs (202 lines):
diff -r 146ca83393c6 -r 5607f866fd94 src/lib-sieve/plugins/mime/cmd-foreverypart.c
--- a/src/lib-sieve/plugins/mime/cmd-foreverypart.c Sun Nov 29 12:17:32 2015 +0100
+++ b/src/lib-sieve/plugins/mime/cmd-foreverypart.c Sun Nov 29 13:00:38 2015 +0100
@@ -2,6 +2,7 @@
*/
#include "sieve-common.h"
+#include "sieve-limits.h"
#include "sieve-code.h"
#include "sieve-extensions.h"
#include "sieve-commands.h"
@@ -28,6 +29,8 @@
struct sieve_command_registration *cmd_reg);
static bool cmd_foreverypart_pre_validate
(struct sieve_validator *valdtr, struct sieve_command *cmd);
+static bool cmd_foreverypart_validate
+ (struct sieve_validator *valdtr, struct sieve_command *cmd);
static bool cmd_foreverypart_generate
(const struct sieve_codegen_env *cgenv,
struct sieve_command *ctx);
@@ -38,7 +41,8 @@
0, 0, TRUE, TRUE,
cmd_foreverypart_registered,
cmd_foreverypart_pre_validate,
- NULL, NULL,
+ cmd_foreverypart_validate,
+ NULL,
cmd_foreverypart_generate,
NULL,
};
@@ -149,6 +153,36 @@
return TRUE;
}
+static bool cmd_foreverypart_validate
+(struct sieve_validator *valdtr, struct sieve_command *cmd)
+{
+ struct sieve_ast_node *node = cmd->ast_node;
+ unsigned int nesting = 0;
+
+ /* Determine nesting depth of foreverypart commands at this point. */
+ i_assert(node != NULL);
+ node = sieve_ast_node_parent(node);
+ while ( node != NULL && node->command != NULL ) {
+ if ( sieve_command_is(node->command, cmd_foreverypart) )
+ nesting++;
+ node = sieve_ast_node_parent(node);
+ }
+
+ /* Enforce nesting limit
+ NOTE: this only recognizes the foreverypart command as a loop; if
+ new loop commands are introduced in the future, these must be
+ recognized somehow. */
+ if ( nesting + 1 > SIEVE_MAX_LOOP_DEPTH ) {
+ sieve_command_validate_error(valdtr, cmd,
+ "the nested foreverypart loop exceeds "
+ "the nesting limit (<= %u levels)",
+ SIEVE_MAX_LOOP_DEPTH);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
/*
* Code generation
*/
@@ -262,10 +296,9 @@
sfploop = ext_foreverypart_runtime_loop_get_current(renv);
- loop = sieve_interpreter_loop_start
- (renv->interp, loop_end, &foreverypart_extension);
- if ( loop == NULL )
- return SIEVE_EXEC_BIN_CORRUPT;
+ if ( (ret=sieve_interpreter_loop_start(renv->interp,
+ loop_end, &foreverypart_extension, &loop)) <= 0 )
+ return ret;
pool = sieve_interpreter_loop_get_pool(loop);
fploop = p_new(pool, struct ext_foreverypart_runtime_loop, 1);
diff -r 146ca83393c6 -r 5607f866fd94 src/lib-sieve/sieve-interpreter.c
--- a/src/lib-sieve/sieve-interpreter.c Sun Nov 29 12:17:32 2015 +0100
+++ b/src/lib-sieve/sieve-interpreter.c Sun Nov 29 13:00:38 2015 +0100
@@ -9,6 +9,7 @@
#include "mail-storage.h"
#include "sieve-common.h"
+#include "sieve-limits.h"
#include "sieve-script.h"
#include "sieve-error.h"
#include "sieve-extensions.h"
@@ -482,9 +483,10 @@
* Loop handling
*/
-struct sieve_interpreter_loop *sieve_interpreter_loop_start
+int sieve_interpreter_loop_start
(struct sieve_interpreter *interp, sieve_size_t loop_end,
- const struct sieve_extension_def *ext_def)
+ const struct sieve_extension_def *ext_def,
+ struct sieve_interpreter_loop **loop_r)
{
const struct sieve_runtime_env *renv = &interp->runenv;
struct sieve_interpreter_loop *loop;
@@ -494,7 +496,7 @@
if ( loop_end > sieve_binary_block_get_size(renv->sblock) ) {
sieve_runtime_trace_error(renv,
"loop end offset out of range");
- return NULL;
+ return SIEVE_EXEC_BIN_CORRUPT;
}
if ( sieve_runtime_trace_active(renv, SIEVE_TRLVL_COMMANDS) ) {
@@ -511,6 +513,15 @@
if ( !array_is_created(&interp->loop_stack) )
p_array_init(&interp->loop_stack, interp->pool, 8);
+ else if ( array_count(&interp->loop_stack)
+ >= SIEVE_MAX_LOOP_DEPTH ) {
+ /* Should normally be caught at compile time */
+ sieve_runtime_error(renv, NULL,
+ "new program loop exceeds "
+ "the nesting limit (<= %u levels)",
+ SIEVE_MAX_LOOP_DEPTH);
+ return SIEVE_EXEC_FAILURE;
+ }
loop = array_append_space(&interp->loop_stack);
loop->level = array_count(&interp->loop_stack)-1;
@@ -519,7 +530,8 @@
loop->end = loop_end;
loop->pool = pool_alloconly_create("sieve_interpreter", 128);
- return loop;
+ *loop_r = loop;
+ return SIEVE_EXEC_OK;
}
struct sieve_interpreter_loop *sieve_interpreter_loop_get
diff -r 146ca83393c6 -r 5607f866fd94 src/lib-sieve/sieve-interpreter.h
--- a/src/lib-sieve/sieve-interpreter.h Sun Nov 29 12:17:32 2015 +0100
+++ b/src/lib-sieve/sieve-interpreter.h Sun Nov 29 13:00:38 2015 +0100
@@ -51,9 +51,10 @@
struct sieve_interpreter_loop;
-struct sieve_interpreter_loop *sieve_interpreter_loop_start
+int sieve_interpreter_loop_start
(struct sieve_interpreter *interp, sieve_size_t loop_end,
- const struct sieve_extension_def *ext_def);
+ const struct sieve_extension_def *ext_def,
+ struct sieve_interpreter_loop **loop_r);
struct sieve_interpreter_loop *sieve_interpreter_loop_get
(struct sieve_interpreter *interp, sieve_size_t loop_end,
const struct sieve_extension_def *ext_def);
diff -r 146ca83393c6 -r 5607f866fd94 src/lib-sieve/sieve-limits.h
--- a/src/lib-sieve/sieve-limits.h Sun Nov 29 12:17:32 2015 +0100
+++ b/src/lib-sieve/sieve-limits.h Sun Nov 29 13:00:38 2015 +0100
@@ -12,6 +12,8 @@
#define SIEVE_DEFAULT_MAX_SCRIPT_SIZE (1 << 20)
+#define SIEVE_MAX_LOOP_DEPTH 4
+
/*
* Lexer
*/
diff -r 146ca83393c6 -r 5607f866fd94 tests/extensions/mime/errors.svtest
--- a/tests/extensions/mime/errors.svtest Sun Nov 29 12:17:32 2015 +0100
+++ b/tests/extensions/mime/errors.svtest Sun Nov 29 13:00:38 2015 +0100
@@ -52,3 +52,13 @@
test_fail "incorrect number of compile errors reported";
}
}
+
+test "Limits" {
+ if test_script_compile "errors/limits.sieve" {
+ test_fail "compile should have failed";
+ }
+
+ if test_error :count "ne" :comparator "i;ascii-numeric" "2" {
+ test_fail "incorrect number of compile errors reported";
+ }
+}
diff -r 146ca83393c6 -r 5607f866fd94 tests/extensions/mime/errors/limits.sieve
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/extensions/mime/errors/limits.sieve Sun Nov 29 13:00:38 2015 +0100
@@ -0,0 +1,13 @@
+require "foreverypart";
+
+foreverypart :name "frop" {
+ foreverypart :name "friep" {
+ foreverypart :name "frml" {
+ foreverypart {
+ foreverypart {
+ break;
+ }
+ }
+ }
+ }
+}
More information about the dovecot-cvs
mailing list