#244 Fix explicit NULL deref around encrypted token processing
Merged 5 years ago by rharwood. Opened 5 years ago by rharwood.
rharwood/gssproxy padding  into  master

file modified
+37 -5
@@ -193,6 +193,9 @@ 

      return ret_maj;

  }

  

+ /* We need to include a length in our payloads because krb5_c_decrypt() will

+  * pad the contents for some enctypes, and gss_import_cred() doesn't like

+  * having extra bytes on tokens. */

  static int gp_encrypt_buffer(krb5_context context, krb5_keyblock *key,

                               size_t len, void *buf, octet_string *out)

  {
@@ -200,9 +203,27 @@ 

      krb5_data data_in;

      krb5_enc_data enc_handle;

      size_t cipherlen;

+     char *packed = NULL;

+     uint32_t netlen;

  

-     data_in.length = len;

-     data_in.data = buf;

+     if (len > (uint32_t)(-1)) {

+         /* Needs to fit in 4 bytes of payload, so... */

+         ret = ENOMEM;

+         goto done;

+     }

+ 

+     packed = malloc(len);

+     if (!packed) {

+         ret = errno;

+         goto done;

+     }

+ 

+     netlen = htonl(len);

+     memcpy(packed, (uint8_t *)&netlen, 4);

+     memcpy(packed + 4, buf, len);

+ 

+     data_in.length = len + 4;

+     data_in.data = packed;

  

      memset(&enc_handle, '\0', sizeof(krb5_enc_data));

  
@@ -240,16 +261,19 @@ 

      }

  

  done:

+     free(packed);

      free(enc_handle.ciphertext.data);

      return ret;

  }

  

+ /* See comment above on gp_encrypt_buffer(). */

  static int gp_decrypt_buffer(krb5_context context, krb5_keyblock *key,

-                              octet_string *in, size_t *len, void *buf)

+                              octet_string *in, size_t *len, char *buf)

  {

      int ret;

      krb5_data data_out;

      krb5_enc_data enc_handle;

+     uint32_t netlen;

  

      memset(&enc_handle, '\0', sizeof(krb5_enc_data));

  
@@ -270,7 +294,10 @@ 

          return ret;

      }

  

-     *len = data_out.length;

+     /* And handle the padding. */

+     memcpy(&netlen, buf, 4);

+     *len = ntohl(netlen);

+     memmove(buf, buf + 4, *len);

  

      return 0;

  }
@@ -449,6 +476,8 @@ 

      uint32_t ret_min = 0;

      int ret;

  

+     *out = GSS_C_NO_CREDENTIAL;

+ 

      handle = gp_service_get_creds_handle(gpcall->service);

      if (!handle) {

          ret_maj = GSS_S_FAILURE;
@@ -470,11 +499,14 @@ 

      if (ret) {

          /* Allow for re-issuance of the keytab. */

          GPDEBUG("Stored ccache failed to decrypt; treating as empty\n");

-         *out = GSS_C_NO_CREDENTIAL;

          goto done;

      }

  

      ret_maj = gss_import_cred(&ret_min, &token, out);

+     if (ret_maj) {

+         GPDEBUG("gss_import_cred failed when importing gssx cred\n");

+         goto done;

+     }

  

      /* check if there is any client option we need to set on credentials */

      gp_set_cred_options(cred, *out);

Can we change this to be less clever and align safe ?
Like:

uint32_t buflen;
memcpy(&buflen, buf, 4);
*len = ntohl(*buflen);

3 new commits added

  • Include length when using krb5_c_decrypt()
  • Handle gss_import_cred() failure when importing gssx creds
  • Always initialize out cred in gp_import_gssx_cred()
5 years ago

Sure, updated. (The cast-style is what postgres does, and I don't like it either.)

Commit 87957ca fixes this pull-request

Pull-Request has been merged by rharwood

5 years ago

Commit 84cf88f fixes this pull-request

Pull-Request has been merged by rharwood

5 years ago

Commit 5697dfd fixes this pull-request

Pull-Request has been merged by rharwood

5 years ago