Tighten up the error handling in the mechglue's gss_canonicalize_name,
authorGreg Hudson <ghudson@mit.edu>
Mon, 10 Jan 2011 20:32:56 +0000 (20:32 +0000)
committerGreg Hudson <ghudson@mit.edu>
Mon, 10 Jan 2011 20:32:56 +0000 (20:32 +0000)
eliminating a null pointer dereference in the (unlikely) case that
allocation of out_union fails.  Reported by aberry@likewise.com.

ticket: 6817

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

src/lib/gssapi/mechglue/g_canon_name.c

index 3d371c0e0422155f2f6efab33bb2e4b6fdf12bde..51e5ae48eb5b6b96141658892923dfa26550a41e 100644 (file)
@@ -64,7 +64,7 @@ const gss_OID mech_type;
 gss_name_t *output_name;
 {
        gss_union_name_t in_union, out_union = NULL, dest_union = NULL;
-       OM_uint32 major_status = GSS_S_FAILURE;
+       OM_uint32 major_status = GSS_S_FAILURE, tmpmin;
 
        major_status = val_canon_name_args(minor_status,
                                           input_name,
@@ -151,38 +151,20 @@ gss_name_t *output_name;
        return (GSS_S_COMPLETE);
 
 allocation_failure:
-       /* do not delete the src name external name format */
-       if (output_name) {
-               if (out_union->external_name) {
-                       if (out_union->external_name->value)
-                               free(out_union->external_name->value);
-                       free(out_union->external_name);
-               }
-               if (out_union->name_type)
-                       (void) gss_release_oid(minor_status,
-                                           &out_union->name_type);
-
-               dest_union = out_union;
-       } else
-               dest_union = in_union;
-
-       /*
-        * delete the partially created mech specific name
-        * applies for both src and dest which ever is being used for output
-        */
-
-       if (dest_union->mech_name) {
-               (void) gssint_release_internal_name(minor_status,
-                                               dest_union->mech_type,
-                                               &dest_union->mech_name);
+       if (out_union) {
+           /* Release the partly constructed out_union. */
+           gss_name_t name = (gss_name_t)out_union;
+           (void) gss_release_name(&tmpmin, &name);
+       } else if (!output_name) {
+           /* Release only the mech name fields in in_union. */
+           if (in_union->mech_name) {
+               (void) gssint_release_internal_name(&tmpmin,
+                                                   dest_union->mech_type,
+                                                   &dest_union->mech_name);
+           }
+           if (in_union->mech_type)
+               (void) gss_release_oid(&tmpmin, &dest_union->mech_type);
        }
 
-       if (dest_union->mech_type)
-               (void) gss_release_oid(minor_status, &dest_union->mech_type);
-
-
-       if (output_name)
-               free(out_union);
-
        return (major_status);
 } /**********  gss_canonicalize_name ********/