From 559142da6023e5309345faa738f6d1bc36b66ea8 Mon Sep 17 00:00:00 2001 From: Paul Arthur Date: Tue, 11 Dec 2018 20:07:40 +0000 Subject: [PATCH 1/2] Fix a buffer overrun in arc_eoh() `strncpy(hnbuf, h->hdr_text, h->hdr_namelen)` assumes that hdr_namelen will never be longer than ARC_MAXHEADER, but that assumption wasn't enforced anywhere. Enforcing the maximum header name length in arc_parse_header_field() seems reasonable, and prevents malformed headers from overrunning this buffer. --- libopenarc/arc.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/libopenarc/arc.c b/libopenarc/arc.c index b1b0b29c..8dd2990c 100644 --- a/libopenarc/arc.c +++ b/libopenarc/arc.c @@ -2407,6 +2407,10 @@ arc_parse_header_field(ARC_MESSAGE *msg, u_char *hdr, size_t hlen, while (end > hdr && isascii(*(end - 1)) && isspace(*(end - 1))) end--; + /* don't allow incredibly large field names */ + if (end - hdr > ARC_MAXHEADER) + return ARC_STAT_SYNTAX; + /* don't allow a field name containing a semicolon */ semicolon = memchr(hdr, ';', hlen); if (semicolon != NULL && colon != NULL && semicolon < colon) @@ -2755,6 +2759,7 @@ arc_eoh(ARC_MESSAGE *msg) for (h = msg->arc_hhead; h != NULL; h = h->hdr_next) { char hnbuf[ARC_MAXHEADER + 1]; + assert(h->hdr_namelen <= ARC_MAXHEADER); memset(hnbuf, '\0', sizeof hnbuf); strncpy(hnbuf, h->hdr_text, h->hdr_namelen); From b2fd0c8028a0aee33baf3e3d359d501c683dad44 Mon Sep 17 00:00:00 2001 From: FUTATSUKI Yasuhito Date: Thu, 19 Sep 2024 05:26:38 +0900 Subject: [PATCH 2/2] libopenarc: Check length of header field name more tightly. From the restriction of RFC5322 section 2.1.1 and section 2.2, length of email header field name cannot be more than 997. With this commit, we define a constant macro for it, and then apply this restriction on parsing header field. Also, reduce size of a buffer for copying header field name. * libopenarc/arc.h (ARC_MAXLINELEN, ARC_MAXHDRNAMELEN): New macros. * libopenarc/arc.c (arc_parse_header_field, ar_eoh): Use ARC_MAXHDRNAMELEN as maximum length of header field names. --- libopenarc/arc.c | 6 +++--- libopenarc/arc.h | 2 ++ 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/libopenarc/arc.c b/libopenarc/arc.c index 1b0a7ad9..781b4448 100644 --- a/libopenarc/arc.c +++ b/libopenarc/arc.c @@ -2412,7 +2412,7 @@ arc_parse_header_field(ARC_MESSAGE *msg, u_char *hdr, size_t hlen, end--; /* don't allow incredibly large field names */ - if (end - hdr > ARC_MAXHEADER) + if (end - hdr > ARC_MAXHDRNAMELEN) return ARC_STAT_SYNTAX; /* don't allow a field name containing a semicolon */ @@ -2762,8 +2762,8 @@ arc_eoh(ARC_MESSAGE *msg) for (h = msg->arc_hhead; h != NULL; h = h->hdr_next) { - char hnbuf[ARC_MAXHEADER + 1]; - assert(h->hdr_namelen <= ARC_MAXHEADER); + char hnbuf[ARC_MAXHDRNAMELEN + 1]; + assert(h->hdr_namelen <= ARC_MAXHDRNAMELEN); memset(hnbuf, '\0', sizeof hnbuf); strncpy(hnbuf, h->hdr_text, h->hdr_namelen); diff --git a/libopenarc/arc.h b/libopenarc/arc.h index 34cf0736..d8107404 100644 --- a/libopenarc/arc.h +++ b/libopenarc/arc.h @@ -46,6 +46,8 @@ extern "C" { #define ARC_HDRMARGIN 75 /* "standard" header margin */ #define ARC_MAXHEADER 4096 /* buffer for caching one header */ #define ARC_MAXHOSTNAMELEN 256 /* max. FQDN we support */ +#define ARC_MAXLINELEN 1000 /* physical line limit (RFC5321) */ +#define ARC_MAXHDRNAMELEN (ARC_MAXLINELEN - 3) /* deduct ":" CRLF */ #define ARC_AR_HDRNAME "ARC-Authentication-Results" #define ARC_DEFAULT_MINKEYSIZE 1024