aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@rspamd.com>2024-05-20 03:32:08 +0600
committerGitHub <noreply@github.com>2024-05-20 03:32:08 +0600
commitd3b7e175511d4637c1e82412b0bece8c1b3acc57 (patch)
tree2faa4429976e5f2e14afb0ac6313432235c3e8ec
parentc8ba300182caefc6f3841442d12ca47fc44ad01f (diff)
parentf73fddc5f18b254e6ccfc23e2267ba053c4bf328 (diff)
downloadrspamd-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.c4
-rw-r--r--src/libserver/dkim.c31
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;
}