Merge branch '2416-tls-certificate-fix-invalid-read' into 'master'

tests/tls-certificate: Add a unit test

Closes #2416

See merge request GNOME/glib!2136
This commit is contained in:
Philip Withnall 2021-06-07 08:36:12 +00:00
commit b407d46c9a
2 changed files with 38 additions and 3 deletions

View File

@ -353,6 +353,7 @@ parse_private_key (const gchar *data,
GError **error)
{
const gchar *header_start = NULL, *header_end, *footer_start = NULL, *footer_end;
const gchar *data_end = data + data_len;
header_end = g_strstr_len (data, data_len, PEM_PRIVKEY_HEADER_END);
if (header_end)
@ -389,7 +390,7 @@ parse_private_key (const gchar *data,
footer_end += strlen (PEM_PRIVKEY_FOOTER_END);
while (*footer_end == '\r' || *footer_end == '\n')
while ((footer_end < data_end) && (*footer_end == '\r' || *footer_end == '\n'))
footer_end++;
return g_strndup (header_start, footer_end - header_start);
@ -423,7 +424,7 @@ parse_next_pem_certificate (const gchar **data,
return NULL;
}
end += strlen (PEM_CERTIFICATE_FOOTER);
while (*end == '\r' || *end == '\n')
while ((end < data_end) && (*end == '\r' || *end == '\n'))
end++;
*data = end;
@ -455,7 +456,7 @@ parse_and_create_certificate_list (const gchar *data,
/* If we read one certificate successfully, let's see if we can read
* some more. If not, we will simply return a list with the first one.
*/
while (p && *p)
while (p < end && p && *p)
{
gchar *cert_pem;
GError *error = NULL;

View File

@ -200,6 +200,38 @@ pem_parser_handles_chain (const Reference *ref)
g_object_unref (original_cert);
}
static void
pem_parser_no_sentinel (void)
{
GTlsCertificate *cert;
gchar *pem;
gsize pem_len = 0;
gchar *pem_copy;
GError *error = NULL;
/* Check certificate from not-nul-terminated PEM */
g_file_get_contents (g_test_get_filename (G_TEST_DIST, "cert-tests", "cert1.pem", NULL), &pem, &pem_len, &error);
g_assert_no_error (error);
g_assert_nonnull (pem);
g_assert_cmpuint (pem_len, >=, 10);
pem_copy = g_new (char, pem_len);
/* Do not copy the terminating nul: */
memmove (pem_copy, pem, pem_len);
g_free (pem);
/* Check whether the parser respects the @length parameter.
* pem_copy is allocated exactly pem_len bytes, so accessing memory
* outside its bounds will be detected by, for example, valgrind or
* asan. */
cert = g_tls_certificate_new_from_pem (pem_copy, pem_len, &error);
g_assert_no_error (error);
g_assert_nonnull (cert);
g_free (pem_copy);
g_object_unref (cert);
}
static void
from_file (const Reference *ref)
{
@ -594,6 +626,8 @@ main (int argc,
subject_name);
g_test_add_func ("/tls-certificate/issuer-name",
issuer_name);
g_test_add_func ("/tls-certificate/pem-parser-no-sentinel",
pem_parser_no_sentinel);
rtv = g_test_run();