[gtk-vnc] ard: cleanup properly



commit b3bf6d97227614db64b2d4da4af75ab734b34b7c
Author: Jakub Janků <jjanku redhat com>
Date:   Wed May 5 21:48:45 2021 +0200

    ard: cleanup properly
    
    With the current code, if one of the gcry functions in
    vnc_connection_perform_auth_ard() fails:
    * key isn't released
    * md5 isn't closed
    * mpis and dh aren't released
    
    Signed-off-by: Jakub Janků <jjanku redhat com>

 src/vncconnection.c | 67 +++++++++++++++++------------------------------------
 1 file changed, 21 insertions(+), 46 deletions(-)
---
diff --git a/src/vncconnection.c b/src/vncconnection.c
index 2d64642..5271274 100644
--- a/src/vncconnection.c
+++ b/src/vncconnection.c
@@ -4157,30 +4157,14 @@ static gboolean vnc_connection_perform_auth_ard(VncConnection *conn)
 
     keylen = 256*len[0] + len[1];
     mod = malloc(keylen);
-    if (mod == NULL) {
-        VNC_DEBUG("malloc failed\n");
-        return FALSE;
-    }
     resp = malloc(keylen);
-    if (resp == NULL) {
-        free(mod);
-        VNC_DEBUG("malloc failed\n");
-        return FALSE;
-    }
     pub = malloc(keylen);
-    if (pub == NULL) {
-        free(resp);
-        free(mod);
-        VNC_DEBUG("malloc failed\n");
-        return FALSE;
-    }
     key = malloc(keylen);
-    if (key == NULL) {
-        free(pub);
-        free(resp);
-        free(mod);
+    if (mod == NULL || resp == NULL
+            || pub == NULL || key == NULL) {
         VNC_DEBUG("malloc failed\n");
-        return FALSE;
+        error = GPG_ERR_ENOMEM;
+        goto cleanup_mem;
     }
 
     vnc_connection_read(conn, mod, keylen);
@@ -4201,19 +4185,13 @@ static gboolean vnc_connection_perform_auth_ard(VncConnection *conn)
     error=gcry_md_open(&md5, GCRY_MD_MD5, 0);
     if (gcry_err_code (error) != GPG_ERR_NO_ERROR) {
         VNC_DEBUG("gcry_md_open error: %s\n", gcry_strerror(error));
-        free(pub);
-        free(resp);
-        free(mod);
-        return FALSE;
+        goto cleanup_mpi;
     }
     gcry_md_write(md5, key, keylen);
     error=gcry_md_final(md5);
     if (gcry_err_code (error) != GPG_ERR_NO_ERROR) {
         VNC_DEBUG("gcry_md_final error: %s\n", gcry_strerror(error));
-        free(pub);
-        free(resp);
-        free(mod);
-        return FALSE;
+        goto cleanup_md5;
     }
     shared = gcry_md_read(md5, GCRY_MD_MD5);
 
@@ -4231,44 +4209,41 @@ static gboolean vnc_connection_perform_auth_ard(VncConnection *conn)
     error=gcry_cipher_open(&aes, GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_ECB, 0);
     if (gcry_err_code (error) != GPG_ERR_NO_ERROR) {
         VNC_DEBUG("gcry_cipher_open error: %s\n", gcry_strerror(error));
-        free(pub);
-        free(resp);
-        free(mod);
-        return FALSE;
+        goto cleanup_md5;
     }
     error=gcry_cipher_setkey(aes, shared, 16);
     if (gcry_err_code (error) != GPG_ERR_NO_ERROR) {
         VNC_DEBUG("gcry_cipher_setkey error: %s\n", gcry_strerror(error));
-        free(pub);
-        free(resp);
-        free(mod);
-        gcry_cipher_close(aes);
-        return FALSE;
+        goto cleanup;
     }
     error=gcry_cipher_encrypt(aes, ciphertext, sizeof(ciphertext), userpass, sizeof(userpass));
     if (gcry_err_code (error) != GPG_ERR_NO_ERROR) {
         VNC_DEBUG("gcry_cipher_encrypt error: %s\n", gcry_strerror(error));
-        free(pub);
-        free(resp);
-        free(mod);
-        gcry_cipher_close(aes);
-        return FALSE;
+        goto cleanup;
     }
 
     vnc_connection_write(conn, ciphertext, sizeof(ciphertext));
     vnc_connection_write(conn, pub, keylen);
     vnc_connection_flush(conn);
 
-    free(mod);
-    free(resp);
-    free(pub);
-    free(key);
+cleanup:
     gcry_cipher_close(aes);
+cleanup_md5:
     gcry_md_close(md5);
+cleanup_mpi:
     gcry_mpi_release(genmpi);
     gcry_mpi_release(modmpi);
     gcry_mpi_release(respmpi);
     vnc_dh_free (dh);
+cleanup_mem:
+    free(mod);
+    free(resp);
+    free(pub);
+    free(key);
+
+    if (gcry_err_code(error) != GPG_ERR_NO_ERROR) {
+        return FALSE;
+    }
 
     return vnc_connection_check_auth_result(conn);
 }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]