[PATCH] sexp: Add length check DATALEN when parsing SEXP.
NIIBE Yutaka via Gcrypt-devel <[email protected]> Wed, 3 Jun 2026 14:47:00 +0900
| Newsgroups | gmane.comp.encryption.gpg.libgcrypt.devel |
|---|---|
| Message-ID | <30365d270bc6aa7dc8a03c8693c7fa086defcc2c.1780465526.git.gniibe@fsij.org> |
This is a multi-part message in MIME format. --------------2.47.3 Content-Type: text/plain; charset=UTF-8; format=fixed Content-Transfer-Encoding: 8bit * src/sexp.c (do_vsexp_sscan): Raise an error when the length cannot be represented by the DATALEN type. -- Reported-by: Ciwan Ă–ztopal GnuPG-bug-id: 8267 Signed-off-by: NIIBE Yutaka <[email protected]> --- src/sexp.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 56 insertions(+), 2 deletions(-) --------------2.47.3 Content-Type: text/x-patch; name="0001-sexp-Add-length-check-DATALEN-when-parsing-SEXP.patch" Content-Transfer-Encoding: 8bit Content-Disposition: attachment; filename="0001-sexp-Add-length-check-DATALEN-when-parsing-SEXP.patch" diff --git a/src/sexp.c b/src/sexp.c index c77d0212..b85fcfee 100644 --- a/src/sexp.c +++ b/src/sexp.c @@ -1189,6 +1189,12 @@ do_vsexp_sscan (gcry_sexp_t *retsexp, size_t *erroff, else { datalen = p - tokenp; + if (datalen > 65535) + { + *erroff = p - buffer; + err = GPG_ERR_INV_ARG; + goto leave; + } MAKE_SPACE (datalen); *c.pos++ = ST_DATA; STORE_LEN (c.pos, datalen); @@ -1281,6 +1287,12 @@ do_vsexp_sscan (gcry_sexp_t *retsexp, size_t *erroff, STORE_LEN (c.pos, 0); /* Will be fixed up later. */ len = unquote_string (quoted, p - quoted, c.pos); c.pos += len; + if (len > 65535) + { + *erroff = p - buffer; + err = GPG_ERR_INV_ARG; + goto leave; + } STORE_LEN (save, len); quoted = NULL; } @@ -1299,6 +1311,12 @@ do_vsexp_sscan (gcry_sexp_t *retsexp, size_t *erroff, } datalen = hexcount / 2; + if (datalen > 65535) + { + *erroff = p - buffer; + err = GPG_ERR_INV_ARG; + goto leave; + } MAKE_SPACE (datalen); *c.pos++ = ST_DATA; STORE_LEN (c.pos, datalen); @@ -1368,6 +1386,13 @@ do_vsexp_sscan (gcry_sexp_t *retsexp, size_t *erroff, goto leave; } + if (datalen > 65535) + { + *erroff = p - buffer; + err = GPG_ERR_INV_ARG; + goto leave; + } + MAKE_SPACE (datalen); *c.pos++ = ST_DATA; STORE_LEN (c.pos, datalen); @@ -1390,8 +1415,16 @@ do_vsexp_sscan (gcry_sexp_t *retsexp, size_t *erroff, ; else if (*p == ':') { - datalen = atoi (digptr); /* FIXME: check for overflow. */ + char *endptr; + + datalen = strtoul (digptr, &endptr, 10); digptr = NULL; + if (endptr != p || datalen > 65535) + { + *erroff = p - buffer; + err = GPG_ERR_INV_ARG; + goto leave; + } if (datalen > n - 1) { *erroff = p - buffer; @@ -1453,6 +1486,13 @@ do_vsexp_sscan (gcry_sexp_t *retsexp, size_t *erroff, nm = (nbits+7)/8; if (mp && nm) { + if (nm > 65535) + { + *erroff = p - buffer; + err = GPG_ERR_INV_ARG; + goto leave; + } + MAKE_SPACE (nm); if (!_gcry_is_secure (c.sexp->d) && mpi_get_flag (m, GCRYMPI_FLAG_SECURE)) @@ -1493,6 +1533,13 @@ do_vsexp_sscan (gcry_sexp_t *retsexp, size_t *erroff, if (err) goto leave; + if (nm > 65535) + { + *erroff = p - buffer; + err = GPG_ERR_INV_ARG; + goto leave; + } + MAKE_SPACE (nm); if (!_gcry_is_secure (c.sexp->d) && mpi_get_flag ( m, GCRYMPI_FLAG_SECURE)) @@ -1532,6 +1579,13 @@ do_vsexp_sscan (gcry_sexp_t *retsexp, size_t *erroff, ARG_NEXT (astr, const char *); alen = strlen (astr); + if (alen > 65535) + { + *erroff = p - buffer; + err = GPG_ERR_INV_ARG; + goto leave; + } + MAKE_SPACE (alen); *c.pos++ = ST_DATA; STORE_LEN (c.pos, alen); @@ -1547,7 +1601,7 @@ do_vsexp_sscan (gcry_sexp_t *retsexp, size_t *erroff, ARG_NEXT (alen, int); ARG_NEXT (astr, const char *); - if (alen < 0) + if (alen < 0 || alen > 65535) { *erroff = p - buffer; err = GPG_ERR_INV_ARG; --------------2.47.3 Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline _______________________________________________ Gcrypt-devel mailing list [email protected] https://lists.gnupg.org/mailman/listinfo/gcrypt-devel --------------2.47.3--