Imported Upstream version 1.15.1
[platform/upstream/krb5.git] / src / plugins / kdb / db2 / kdb_xdr.c
index 184615c..694c759 100644 (file)
@@ -232,6 +232,8 @@ krb5_decode_princ_entry(krb5_context context, krb5_data *content,
     krb5_db_entry       * entry;
     krb5_error_code retval;
 
+    *entry_ptr = NULL;
+
     entry = k5alloc(sizeof(*entry), &retval);
     if (entry == NULL)
         return retval;
@@ -248,10 +250,11 @@ krb5_decode_princ_entry(krb5_context context, krb5_data *content,
     /* First do the easy stuff */
     nextloc = (unsigned char *)content->data;
     sizeleft = content->length;
-    if ((sizeleft -= KRB5_KDB_V1_BASE_LENGTH) < 0) {
+    if (sizeleft < KRB5_KDB_V1_BASE_LENGTH) {
         retval = KRB5_KDB_TRUNCATED_RECORD;
         goto error_out;
     }
+    sizeleft -= KRB5_KDB_V1_BASE_LENGTH;
 
     /* Base Length */
     krb5_kdb_decode_int16(nextloc, entry->len);
@@ -310,10 +313,9 @@ krb5_decode_princ_entry(krb5_context context, krb5_data *content,
     /* Check for extra data */
     if (entry->len > KRB5_KDB_V1_BASE_LENGTH) {
         entry->e_length = entry->len - KRB5_KDB_V1_BASE_LENGTH;
-        entry->e_data = k5alloc(entry->e_length, &retval);
+        entry->e_data = k5memdup(nextloc, entry->e_length, &retval);
         if (entry->e_data == NULL)
             goto error_out;
-        memcpy(entry->e_data, nextloc, entry->e_length);
         nextloc += entry->e_length;
     }
 
@@ -321,32 +323,35 @@ krb5_decode_princ_entry(krb5_context context, krb5_data *content,
      * Get the principal name for the entry
      * (stored as a string which gets unparsed.)
      */
-    if ((sizeleft -= 2) < 0) {
+    if (sizeleft < 2) {
         retval = KRB5_KDB_TRUNCATED_RECORD;
         goto error_out;
     }
+    sizeleft -= 2;
 
     i = 0;
     krb5_kdb_decode_int16(nextloc, i16);
     i = (int) i16;
     nextloc += 2;
-
-    if ((retval = krb5_parse_name(context, (char *)nextloc, &(entry->princ))))
-        goto error_out;
-    if (((size_t) i != (strlen((char *)nextloc) + 1)) || (sizeleft < i)) {
+    if (i <= 0 || i > sizeleft || nextloc[i - 1] != '\0' ||
+        memchr((char *)nextloc, '\0', i - 1) != NULL) {
         retval = KRB5_KDB_TRUNCATED_RECORD;
         goto error_out;
     }
+
+    if ((retval = krb5_parse_name(context, (char *)nextloc, &(entry->princ))))
+        goto error_out;
     sizeleft -= i;
     nextloc += i;
 
     /* tl_data is a linked list */
     tl_data = &entry->tl_data;
     for (i = 0; i < entry->n_tl_data; i++) {
-        if ((sizeleft -= 4) < 0) {
+        if (sizeleft < 4) {
             retval = KRB5_KDB_TRUNCATED_RECORD;
             goto error_out;
         }
+        sizeleft -= 4;
         if ((*tl_data = (krb5_tl_data *)
              malloc(sizeof(krb5_tl_data))) == NULL) {
             retval = ENOMEM;
@@ -359,16 +364,15 @@ krb5_decode_princ_entry(krb5_context context, krb5_data *content,
         krb5_kdb_decode_int16(nextloc, (*tl_data)->tl_data_length);
         nextloc += 2;
 
-        if ((sizeleft -= (*tl_data)->tl_data_length) < 0) {
+        if ((*tl_data)->tl_data_length > sizeleft) {
             retval = KRB5_KDB_TRUNCATED_RECORD;
             goto error_out;
         }
-        if (((*tl_data)->tl_data_contents = (krb5_octet *)
-             malloc((*tl_data)->tl_data_length)) == NULL) {
-            retval = ENOMEM;
+        sizeleft -= (*tl_data)->tl_data_length;
+        (*tl_data)->tl_data_contents =
+            k5memdup(nextloc, (*tl_data)->tl_data_length, &retval);
+        if ((*tl_data)->tl_data_contents == NULL)
             goto error_out;
-        }
-        memcpy((*tl_data)->tl_data_contents,nextloc,(*tl_data)->tl_data_length);
         nextloc += (*tl_data)->tl_data_length;
         tl_data = &((*tl_data)->tl_data_next);
     }
@@ -383,10 +387,11 @@ krb5_decode_princ_entry(krb5_context context, krb5_data *content,
         krb5_key_data * key_data;
         int j;
 
-        if ((sizeleft -= 4) < 0) {
+        if (sizeleft < 4) {
             retval = KRB5_KDB_TRUNCATED_RECORD;
             goto error_out;
         }
+        sizeleft -= 4;
         key_data = entry->key_data + i;
         memset(key_data, 0, sizeof(krb5_key_data));
         krb5_kdb_decode_int16(nextloc, key_data->key_data_ver);
@@ -395,74 +400,42 @@ krb5_decode_princ_entry(krb5_context context, krb5_data *content,
         nextloc += 2;
 
         /* key_data_ver determins number of elements and how to unparse them. */
-        if (key_data->key_data_ver <= KRB5_KDB_V1_KEY_DATA_ARRAY) {
+        if (key_data->key_data_ver >= 0 &&
+            key_data->key_data_ver <= KRB5_KDB_V1_KEY_DATA_ARRAY) {
             for (j = 0; j < key_data->key_data_ver; j++) {
-                if ((sizeleft -= 4) < 0) {
+                if (sizeleft < 4) {
                     retval = KRB5_KDB_TRUNCATED_RECORD;
                     goto error_out;
                 }
+                sizeleft -= 4;
                 krb5_kdb_decode_int16(nextloc, key_data->key_data_type[j]);
                 nextloc += 2;
                 krb5_kdb_decode_int16(nextloc, key_data->key_data_length[j]);
                 nextloc += 2;
 
-                if ((sizeleft -= key_data->key_data_length[j]) < 0) {
+                if (key_data->key_data_length[j] > sizeleft) {
                     retval = KRB5_KDB_TRUNCATED_RECORD;
                     goto error_out;
                 }
+                sizeleft -= key_data->key_data_length[j];
                 if (key_data->key_data_length[j]) {
-                    if ((key_data->key_data_contents[j] = (krb5_octet *)
-                         malloc(key_data->key_data_length[j])) == NULL) {
-                        retval = ENOMEM;
+                    key_data->key_data_contents[j] =
+                        k5memdup(nextloc, key_data->key_data_length[j],
+                                 &retval);
+                    if (key_data->key_data_contents[j] == NULL)
                         goto error_out;
-                    }
-                    memcpy(key_data->key_data_contents[j], nextloc,
-                           key_data->key_data_length[j]);
                     nextloc += key_data->key_data_length[j];
                 }
             }
         } else {
-            /* This isn't right. I'll fix it later */
-            abort();
+            retval = KRB5_KDB_BAD_VERSION;
+            goto error_out;
         }
     }
     *entry_ptr = entry;
     return 0;
 
 error_out:
-    krb5_dbe_free(context, entry);
+    krb5_db_free_principal(context, entry);
     return retval;
 }
-
-void
-krb5_dbe_free(krb5_context context, krb5_db_entry *entry)
-{
-    krb5_tl_data        * tl_data_next;
-    krb5_tl_data        * tl_data;
-    int i, j;
-
-    if (entry == NULL)
-        return;
-    free(entry->e_data);
-    krb5_free_principal(context, entry->princ);
-    for (tl_data = entry->tl_data; tl_data; tl_data = tl_data_next) {
-        tl_data_next = tl_data->tl_data_next;
-        free(tl_data->tl_data_contents);
-        free(tl_data);
-    }
-    if (entry->key_data) {
-        for (i = 0; i < entry->n_key_data; i++) {
-            for (j = 0; j < entry->key_data[i].key_data_ver; j++) {
-                if (entry->key_data[i].key_data_length[j]) {
-                    zapfree(entry->key_data[i].key_data_contents[j],
-                            entry->key_data[i].key_data_length[j]);
-                }
-                entry->key_data[i].key_data_contents[j] = NULL;
-                entry->key_data[i].key_data_length[j] = 0;
-                entry->key_data[i].key_data_type[j] = 0;
-            }
-        }
-        free(entry->key_data);
-    }
-    free(entry);
-}