If 1024 was not enough to fit the DN, gnutls_x509_crt_get_dn would store the required size in subjectlen. And since we're not checking the return value of this function, we would happily overwrite some random memory. Signed-off-by: Jiri Denemark <jdenemar@xxxxxxxxxx> --- Notes: Version 2: - do not pass NULL to the first gnutls_x509_crt_get_dn call src/qemu/qemu_migration_cookie.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/src/qemu/qemu_migration_cookie.c b/src/qemu/qemu_migration_cookie.c index 76a01781d6..5d14e271c1 100644 --- a/src/qemu/qemu_migration_cookie.c +++ b/src/qemu/qemu_migration_cookie.c @@ -180,12 +180,12 @@ static char * qemuDomainExtractTLSSubject(const char *certdir) { g_autofree char *certfile = NULL; - char *subject = NULL; + g_autofree char *subject = NULL; g_autofree char *pemdata = NULL; gnutls_datum_t pemdatum; gnutls_x509_crt_t cert; int rc; - size_t subjectlen; + size_t subjectlen = 256; certfile = g_strdup_printf("%s/server-cert.pem", certdir); @@ -214,13 +214,21 @@ qemuDomainExtractTLSSubject(const char *certdir) return NULL; } - subjectlen = 1024; subject = g_new0(char, subjectlen + 1); - - gnutls_x509_crt_get_dn(cert, subject, &subjectlen); + rc = gnutls_x509_crt_get_dn(cert, subject, &subjectlen); + if (rc == GNUTLS_E_SHORT_MEMORY_BUFFER) { + subject = g_realloc(subject, subjectlen + 1); + rc = gnutls_x509_crt_get_dn(cert, subject, &subjectlen); + } + if (rc != 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("cannot get cert distinguished name: %s"), + gnutls_strerror(rc)); + return NULL; + } subject[subjectlen] = '\0'; - return subject; + return g_steal_pointer(&subject); } -- 2.35.0