In krb5_ccache_internalize: fix resource leaks, fix several cases
authorGreg Hudson <ghudson@mit.edu>
Tue, 10 Feb 2009 19:05:58 +0000 (19:05 +0000)
committerGreg Hudson <ghudson@mit.edu>
Tue, 10 Feb 2009 19:05:58 +0000 (19:05 +0000)
where success could be returned on failure, validate the length of the
ccache name, make the value of *argp well-defined on failure, and lay
out the function in a linear style with a cleanup handler.

git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@21952 dc483132-0cff-0310-8789-dd5450dbe970

src/lib/krb5/ccache/ser_cc.c

index 88e6a137dd35161ca72f2be65c185c9ec227b20d..33e7f51cc77eb60f638aa4bd488a5a18b9b0ce1f 100644 (file)
@@ -158,36 +158,57 @@ krb5_ccache_internalize(krb5_context kcontext, krb5_pointer *argp, krb5_octet **
     krb5_int32         ibuf;
     krb5_octet         *bp;
     size_t             remain;
-    char               *ccname;
+    char               *ccname = NULL;
+
+    *argp = NULL;
 
     bp = *buffer;
     remain = *lenremain;
-    kret = EINVAL;
-    /* Read our magic number */
-    if (krb5_ser_unpack_int32(&ibuf, &bp, &remain))
-       ibuf = 0;
-    if (ibuf == KV5M_CCACHE) {
-       kret = ENOMEM;
 
-       /* Get the length of the ccache name */
-       kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain);
-
-       if (!kret &&
-           (ccname = (char *) malloc((size_t) (ibuf+1))) &&
-           !(kret = krb5_ser_unpack_bytes((krb5_octet *) ccname,
-                                          (size_t) ibuf,
-                                          &bp, &remain))) {
-           ccname[ibuf] = '\0';
-           if (!(kret = krb5_cc_resolve(kcontext, ccname, &ccache)) &&
-               !(kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain)) &&
-               (ibuf == KV5M_CCACHE)) {
-               *buffer = bp;
-               *lenremain = remain;
-               *argp = (krb5_pointer) ccache;
-           }
-           free(ccname);
-       }
+    /* Read our magic number. */
+    kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain);
+    if (kret)
+       return kret;
+    if (ibuf != KV5M_CCACHE)
+       return EINVAL;
+
+    /* Unpack and validate the length of the ccache name. */
+    kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain);
+    if (kret)
+       return kret;
+    if (ibuf < 0 || ibuf > remain)
+       return EINVAL;
+
+    /* Allocate and unpack the name. */
+    ccname = malloc(ibuf + 1);
+    if (!ccname)
+       return ENOMEM;
+    kret = krb5_ser_unpack_bytes((krb5_octet *) ccname, (size_t) ibuf,
+                                &bp, &remain);
+    if (kret)
+       goto cleanup;
+    ccname[ibuf] = '\0';
+
+    /* Read the second magic number. */
+    kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain);
+    if (kret)
+       goto cleanup;
+    if (ibuf != KV5M_CCACHE) {
+       kret = EINVAL;
+       goto cleanup;
     }
+
+    /* Resolve the named credential cache. */
+    kret = krb5_cc_resolve(kcontext, ccname, &ccache);
+    if (kret)
+       goto cleanup;
+
+    *buffer = bp;
+    *lenremain = remain;
+    *argp = ccache;
+
+cleanup:
+    free(ccname);
     return(kret);
 }
 \f