svn rev #22031: branches/krb5-1-7/src/lib/krb5/krb/

tlyu@MIT.EDU tlyu at MIT.EDU
Wed Feb 18 19:37:03 EST 2009


http://src.mit.edu/fisheye/changelog/krb5/?cs=22031
Commit By: tlyu
Log Message:
ticket: 6376
version_fixed: 1.7
status: resolved

pull up r21912 from trunk

 ------------------------------------------------------------------------
 r21912 | ghudson | 2009-02-06 15:43:44 -0500 (Fri, 06 Feb 2009) | 10 lines
 Changed paths:
    M /trunk/src/lib/krb5/krb/walk_rtree.c

 ticket: 6376
 subject: Memory handling fixes in walk_rtree
 tags: pullup
 target_version: 1.7

 In walk_rtree's rtree_hier_tree, don't leak the result of
 rtree_hier_realms.  In rtree_hier_realms, avoid freeing one too many
 krb5_data contents on allocation failure, and use the recommend
 pattern to ensure well-defined output parameter values.

 ------------------------------------------------------------------------


Changed Files:
U   branches/krb5-1-7/src/lib/krb5/krb/walk_rtree.c
Modified: branches/krb5-1-7/src/lib/krb5/krb/walk_rtree.c
===================================================================
--- branches/krb5-1-7/src/lib/krb5/krb/walk_rtree.c	2009-02-19 00:36:51 UTC (rev 22030)
+++ branches/krb5-1-7/src/lib/krb5/krb/walk_rtree.c	2009-02-19 00:37:02 UTC (rev 22031)
@@ -74,6 +74,12 @@
     size_t *nrealms,
     int sep);
 
+static void
+free_realmlist(
+    krb5_context context,
+    krb5_data *realms,
+    size_t nrealms);
+
 static krb5_error_code
 rtree_hier_tweens(
     krb5_context context,
@@ -333,12 +339,14 @@
 	srcrealm = dstrealm;
     }
     *rettree = tree;
+    free_realmlist(context, realms, nrealms);
     return 0;
 error:
     while (pprinc != NULL && pprinc > tree) {
 	krb5_free_principal(context, *--pprinc);
 	*pprinc = NULL;
     }
+    free_realmlist(context, realms, nrealms);
     free(tree);
     return retval;
 }
@@ -360,6 +368,9 @@
     krb5_data *ctweens, *stweens, *twp, *r, *rp;
     size_t nctween, nstween;
 
+    *realms = NULL;
+    *nrealms = 0;
+
     r = rp = NULL;
     c.str = client->data;
     c.len = client->length;
@@ -376,37 +387,48 @@
     retval = rtree_hier_tweens(context, &s, &stweens, &nstween, 0, sep);
     if (retval) goto error;
 
-    *nrealms = nctween + nstween;
-    rp = r = calloc(*nrealms, sizeof(krb5_data));
+    rp = r = calloc(nctween + nstween, sizeof(krb5_data));
     if (r == NULL) {
 	retval = ENOMEM;
 	goto error;
     }
     /* Copy client realm "tweens" forward. */
     for (twp = ctweens; twp < &ctweens[nctween]; twp++) {
-	retval = krb5int_copy_data_contents(context, twp, rp++);
+	retval = krb5int_copy_data_contents(context, twp, rp);
 	if (retval) goto error;
+	rp++;
     }
     /* Copy server realm "tweens" backward. */
     for (twp = &stweens[nstween]; twp-- > stweens;) {
-	retval = krb5int_copy_data_contents(context, twp, rp++);
+	retval = krb5int_copy_data_contents(context, twp, rp);
 	if (retval) goto error;
+	rp++;
     }
 error:
+    free(ctweens);
+    free(stweens);
     if (retval) {
-	*nrealms = 0;
-	while (rp > r) {
-	    krb5_free_data_contents(context, --rp);
-	}
-	free(r);
-	r = NULL;
+	free_realmlist(context, r, rp - r);
+	return retval;
     }
-    free(ctweens);
-    free(stweens);
     *realms = r;
-    return retval;
+    *nrealms = rp - r;
+    return 0;
 }
 
+static void
+free_realmlist(
+    krb5_context context,
+    krb5_data *realms,
+    size_t nrealms)
+{
+    size_t i;
+
+    for (i = 0; i < nrealms; i++)
+	krb5_free_data_contents(context, &realms[i]);
+    free(realms);
+}
+
 /*
  * Build a list of realms between a given realm and the common
  * suffix.  The original realm is included, but the "tail" is only




More information about the cvs-krb5 mailing list