diff options
author | Vsevolod Stakhov <vsevolod@rspamd.com> | 2024-05-20 03:32:08 +0600 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-05-20 03:32:08 +0600 |
commit | d3b7e175511d4637c1e82412b0bece8c1b3acc57 (patch) | |
tree | 2faa4429976e5f2e14afb0ac6313432235c3e8ec | |
parent | c8ba300182caefc6f3841442d12ca47fc44ad01f (diff) | |
parent | f73fddc5f18b254e6ccfc23e2267ba053c4bf328 (diff) | |
download | rspamd-d3b7e175511d4637c1e82412b0bece8c1b3acc57.tar.gz rspamd-d3b7e175511d4637c1e82412b0bece8c1b3acc57.zip |
Merge pull request #4975 from rspamd/vstakhov-dkim-l-sanity
Verify `l=` tag in DKIM signatures
-rw-r--r-- | contrib/kann/kautodiff.c | 4 | ||||
-rw-r--r-- | src/libserver/dkim.c | 31 |
2 files changed, 29 insertions, 6 deletions
diff --git a/contrib/kann/kautodiff.c b/contrib/kann/kautodiff.c index 34645ab66..551d54861 100644 --- a/contrib/kann/kautodiff.c +++ b/contrib/kann/kautodiff.c @@ -1061,12 +1061,12 @@ bool kad_ssyev_simple(int N, float *A, float *eigenvals) ssyev("Vectors", "Upper", &n, A, &lda, eigenvals, work, &lwork, &info); /* Check for convergence */ if (info > 0) { - g_g_free(work); + g_free(work); return false; } - g_g_free(work); + g_free(work); return true; #endif diff --git a/src/libserver/dkim.c b/src/libserver/dkim.c index 3134b0ecf..742e4db8b 100644 --- a/src/libserver/dkim.c +++ b/src/libserver/dkim.c @@ -2129,7 +2129,8 @@ end: } static gboolean -rspamd_dkim_canonize_body(struct rspamd_dkim_common_ctx *ctx, +rspamd_dkim_canonize_body(struct rspamd_task *task, + struct rspamd_dkim_common_ctx *ctx, const char *start, const char *end, gboolean sign) @@ -2149,7 +2150,20 @@ rspamd_dkim_canonize_body(struct rspamd_dkim_common_ctx *ctx, EVP_DigestUpdate(ctx->body_hash, "", 0); } } - else { + else if (end >= start) { + /* Add sanity checks for ctx->len */ + if (ctx->body_canon_type == DKIM_CANON_SIMPLE && ctx->len > 0) { + if (ctx->len < 2 && end - start > 2) { + msg_info_task("DKIM l tag is invalid: %d (%d actual size)", (int) ctx->len, (int) (end - start)); + return FALSE; + } + if (ctx->len + 2 < (double) (end - start) * 0.9) { + msg_info_task("DKIM l tag does not cover enough of the body: %d (%d actual size)", + (int) ctx->len, (int) (end - start)); + return FALSE; + } + } + /* Strip extra ending CRLF */ p = rspamd_dkim_skip_empty_lines(start, end, ctx->body_canon_type, sign, &need_crlf); @@ -2203,9 +2217,18 @@ rspamd_dkim_canonize_body(struct rspamd_dkim_common_ctx *ctx, } } else { + size_t orig_len = remain; + while (rspamd_dkim_relaxed_body_step(ctx, ctx->body_hash, &start, end - start, &remain)) ; + + if (ctx->len > 0 && remain > (double) orig_len * 0.1) { + msg_info_task("DKIM l tag does not cover enough of the body: %d (%d actual size)", + (int) ctx->len, (int) (end - start)); + return FALSE; + } + if (need_crlf) { start = "\r\n"; end = start + 2; @@ -2719,7 +2742,7 @@ rspamd_dkim_check(rspamd_dkim_context_t *ctx, if (!cached_bh->digest_normal) { /* Start canonization of body part */ - if (!rspamd_dkim_canonize_body(&ctx->common, body_start, body_end, + if (!rspamd_dkim_canonize_body(task, &ctx->common, body_start, body_end, FALSE)) { res->rcode = DKIM_RECORD_ERROR; return res; @@ -3342,7 +3365,7 @@ rspamd_dkim_sign(struct rspamd_task *task, const char *selector, if (!cached_bh->digest_normal) { /* Start canonization of body part */ - if (!rspamd_dkim_canonize_body(&ctx->common, body_start, body_end, + if (!rspamd_dkim_canonize_body(task, &ctx->common, body_start, body_end, TRUE)) { return NULL; } |