diff --git a/src/lib-sieve/sieve-interpreter.c b/src/lib-sieve/sieve-interpreter.c index 42f6ea1c62be0adfe0d33f36a2f10b7777c0b952..47ece881084546ed6921d18f14bf8c84675c72b3 100644 --- a/src/lib-sieve/sieve-interpreter.c +++ b/src/lib-sieve/sieve-interpreter.c @@ -953,7 +953,7 @@ int sieve_interpreter_continue(struct sieve_interpreter *interp, sieve_runtime_error( renv, NULL, "execution exceeded CPU time limit"); - ret = SIEVE_EXEC_FAILURE; + ret = SIEVE_EXEC_RESOURCE_LIMIT; break; } if (interp->loop_limit != 0 && *address > interp->loop_limit) { @@ -998,6 +998,9 @@ int sieve_interpreter_continue(struct sieve_interpreter *interp, case SIEVE_EXEC_BIN_CORRUPT: e->add_str("error", "Binary corrupt"); break; + case SIEVE_EXEC_RESOURCE_LIMIT: + e->add_str("error", "Resource limit exceeded"); + break; case SIEVE_EXEC_KEEP_FAILED: /* Not supposed to occur at runtime */ i_unreached(); diff --git a/src/lib-sieve/sieve-types.h b/src/lib-sieve/sieve-types.h index 5ab027e29987c880e9cfca575f5d13a5bcede573..f2e64a4cda3c0786f87c8420c354e99079666e10 100644 --- a/src/lib-sieve/sieve-types.h +++ b/src/lib-sieve/sieve-types.h @@ -290,11 +290,12 @@ struct sieve_exec_status { */ enum sieve_execution_exitcode { - SIEVE_EXEC_OK = 1, - SIEVE_EXEC_FAILURE = 0, - SIEVE_EXEC_TEMP_FAILURE = -1, - SIEVE_EXEC_BIN_CORRUPT = -2, - SIEVE_EXEC_KEEP_FAILED = -3 + SIEVE_EXEC_OK = 1, + SIEVE_EXEC_FAILURE = 0, + SIEVE_EXEC_TEMP_FAILURE = -1, + SIEVE_EXEC_BIN_CORRUPT = -2, + SIEVE_EXEC_KEEP_FAILED = -3, + SIEVE_EXEC_RESOURCE_LIMIT = -4, }; #endif diff --git a/src/plugins/imap-filter-sieve/imap-filter-sieve.c b/src/plugins/imap-filter-sieve/imap-filter-sieve.c index f3e33017fa0f53cbabdd8853aea09182b21e578c..26369541ff01dd445e648a01048cb8a4752fe233 100644 --- a/src/plugins/imap-filter-sieve/imap-filter-sieve.c +++ b/src/plugins/imap-filter-sieve/imap-filter-sieve.c @@ -728,6 +728,14 @@ imap_sieve_filter_handle_exec_status(struct imap_filter_sieve_context *sctx, *fatal_r = TRUE; ret = -1; break; + case SIEVE_EXEC_RESOURCE_LIMIT: + e_error(sieve_get_event(svinst), + "Execution of script %s was aborted " + "due to excessive resource usage", + sieve_script_location(script)); + *fatal_r = TRUE; + ret = -1; + break; case SIEVE_EXEC_KEEP_FAILED: e_log(sieve_get_event(svinst), log_level, "Execution of script %s failed " diff --git a/src/plugins/imapsieve/imap-sieve.c b/src/plugins/imapsieve/imap-sieve.c index 74d66eb7b07cd41dabd1b7cfd6474308e457bfbf..3ed19ea8f1340e87213927e600665edf84dd79c5 100644 --- a/src/plugins/imapsieve/imap-sieve.c +++ b/src/plugins/imapsieve/imap-sieve.c @@ -636,6 +636,14 @@ imap_sieve_handle_exec_status(struct imap_sieve_run *isrun, *fatal_r = TRUE; ret = -1; break; + case SIEVE_EXEC_RESOURCE_LIMIT: + e_error(sieve_get_event(svinst), + "Execution of script %s was aborted " + "due to excessive resource usage", + sieve_script_location(script)); + *fatal_r = TRUE; + ret = -1; + break; case SIEVE_EXEC_KEEP_FAILED: e_log(sieve_get_event(svinst), log_level, "Execution of script %s failed " diff --git a/src/plugins/lda-sieve/lda-sieve-plugin.c b/src/plugins/lda-sieve/lda-sieve-plugin.c index 0fa323de1f4a168d0502f40ce2a318e5f6412645..175b76ac2311e6a9cb395def508deef863167faf 100644 --- a/src/plugins/lda-sieve/lda-sieve-plugin.c +++ b/src/plugins/lda-sieve/lda-sieve-plugin.c @@ -564,6 +564,8 @@ lda_sieve_execute_script(struct lda_sieve_run_context *srctx, if (mstatus != SIEVE_EXEC_BIN_CORRUPT) lda_sieve_binary_save(srctx, sbin, script); } + if (ret == 0 && mstatus == SIEVE_EXEC_RESOURCE_LIMIT) + ret = -1; sieve_close(&sbin); diff --git a/src/sieve-tools/sieve-filter.c b/src/sieve-tools/sieve-filter.c index d71f4bcad9ef80feac3dce05668bbd1b534eed8f..deaae6abdf7db5d461bc345c973de26da431dfa6 100644 --- a/src/sieve-tools/sieve-filter.c +++ b/src/sieve-tools/sieve-filter.c @@ -237,6 +237,9 @@ static int filter_message(struct sieve_filter_context *sfctx, struct mail *mail) switch (ret) { case SIEVE_EXEC_OK: break; + case SIEVE_EXEC_RESOURCE_LIMIT: + sieve_error(ehandler, NULL, "sieve resource limit exceeded"); + return -1; case SIEVE_EXEC_BIN_CORRUPT: sieve_error(ehandler, NULL, "sieve script binary is corrupt"); return -1; diff --git a/src/sieve-tools/sieve-test.c b/src/sieve-tools/sieve-test.c index b623b67145a5547d04e114c4279a5bc2e00f32fa..c553ace891bbbab6013e942c55d3250c26e25bff 100644 --- a/src/sieve-tools/sieve-test.c +++ b/src/sieve-tools/sieve-test.c @@ -452,6 +452,10 @@ int main(int argc, char **argv) case SIEVE_EXEC_OK: i_info("final result: success"); break; + case SIEVE_EXEC_RESOURCE_LIMIT: + i_info("resource limit exceeded"); + exit_status = EXIT_FAILURE; + break; case SIEVE_EXEC_BIN_CORRUPT: i_info("corrupt binary deleted."); i_unlink_if_exists(sieve_binary_path(sbin)); diff --git a/src/testsuite/testsuite.c b/src/testsuite/testsuite.c index 4cd4ba7228c92d1e15ef673f383f606946b2f11b..2a6b82eb45621dca7bae11b5a45163757f7c988c 100644 --- a/src/testsuite/testsuite.c +++ b/src/testsuite/testsuite.c @@ -222,6 +222,10 @@ int main(int argc, char **argv) testsuite_testcase_fail( "compiled test script binary is corrupt"); break; + case SIEVE_EXEC_RESOURCE_LIMIT: + testsuite_testcase_fail( + "resource limit exceeded"); + break; } sieve_close(&sbin);