* src/lib/gssapi/mechglue/mglueP.h: Add loopback field to opaque
authorTom Yu <tlyu@mit.edu>
Mon, 7 Aug 2006 23:33:39 +0000 (23:33 +0000)
committerTom Yu <tlyu@mit.edu>
Mon, 7 Aug 2006 23:33:39 +0000 (23:33 +0000)
structs of gss_ctx_id_t, gss_name_t, gss_cred_id_t to catch some
application programming errors.  Add new macro GSSINT_CHK_LOOP()
which returns non-zero if loopback field doesn't point to itself.

* src/lib/gssapi/mechglue/g_accept_sec_context.c
(gss_accept_sec_context):
* src/lib/gssapi/mechglue/g_acquire_cred.c (gss_add_cred)
(gss_acquire_cred):
* src/lib/gssapi/mechglue/g_delete_sec_context.c
(gss_delete_sec_context):
* src/lib/gssapi/mechglue/g_glue.c
(gssint_convert_name_to_union_name):
* src/lib/gssapi/mechglue/g_imp_name.c (gss_import_name):
* src/lib/gssapi/mechglue/g_imp_sec_context.c
(gss_import_sec_context):
* src/lib/gssapi/mechglue/g_init_sec_context.c
(gss_init_sec_context): Set loopback pointers.

* src/lib/gssapi/mechglue/g_delete_sec_context.c
(gss_delete_sec_context):
* src/lib/gssapi/mechglue/g_rel_cred.c (gss_release_cred):
* src/lib/gssapi/mechglue/g_rel_name.c (gss_release_name): Call
GSSINT_CHK_LOOP() to validate loopback pointer.

ticket: 4063
tags: pullup

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

src/lib/gssapi/mechglue/g_accept_sec_context.c
src/lib/gssapi/mechglue/g_acquire_cred.c
src/lib/gssapi/mechglue/g_delete_sec_context.c
src/lib/gssapi/mechglue/g_dup_name.c
src/lib/gssapi/mechglue/g_glue.c
src/lib/gssapi/mechglue/g_imp_name.c
src/lib/gssapi/mechglue/g_imp_sec_context.c
src/lib/gssapi/mechglue/g_init_sec_context.c
src/lib/gssapi/mechglue/g_rel_cred.c
src/lib/gssapi/mechglue/g_rel_name.c
src/lib/gssapi/mechglue/mglueP.h

index e0be150937ab73145358573bf584cb4cc9ba3fb7..23ec2869d6fad05c180f1a18aa07d88bb4ac87e5 100644 (file)
@@ -112,6 +112,7 @@ gss_cred_id_t *             d_cred;
        if (!union_ctx_id)
            return (GSS_S_FAILURE);
 
+       union_ctx_id->loopback = union_ctx_id;
        union_ctx_id->internal_ctx_id = GSS_C_NO_CONTEXT;
        status = generic_gss_copy_oid(&temp_minor_status,
                                      token_mech_type,
@@ -239,6 +240,7 @@ gss_cred_id_t *             d_cred;
 
                d_u_cred->auxinfo.creation_time = time(0);
                d_u_cred->auxinfo.time_rec = 0;
+               d_u_cred->loopback = d_u_cred;
 
                if (mech->gss_inquire_cred) {
                    status = mech->gss_inquire_cred(mech->context,
index ca30607911b911e5328527c5d684a6a91f89eb15..d13650c827e9e93a781eee78937447d117ab3c51 100644 (file)
@@ -147,6 +147,7 @@ OM_uint32 *         time_rec;
 
     /* initialize to 0s */
     (void) memset(creds, 0, sizeof (gss_union_cred_desc));
+    creds->loopback = creds;
 
     /* for each requested mech attempt to obtain a credential */
     for (i = 0; i < mechs->count; i++) {
@@ -202,6 +203,7 @@ OM_uint32 *         time_rec;
        *time_rec = outTime;
 
 
+    creds->loopback = creds;
     *output_cred_handle = (gss_cred_id_t)creds;
     return (GSS_S_COMPLETE);
 }
@@ -405,6 +407,7 @@ gss_add_cred(minor_status, input_cred_handle,
     new_union_cred->mechs_array = new_mechs_array;
     new_union_cred->cred_array = new_cred_array;
     new_union_cred->count++;
+    new_union_cred->loopback = new_union_cred;
 
     /* We're done with the internal name. Free it if we allocated it. */
 
index de70b8fb79e61a5d898ea1b09a6dc5a333689423..5d1e8626dd1946df4972b2738344637e492c3d91 100644 (file)
@@ -64,6 +64,8 @@ gss_buffer_t          output_token;
      */
     
     ctx = (gss_union_ctx_id_t) *context_handle;
+    if (GSSINT_CHK_LOOP(ctx))
+       return (GSS_S_CALL_INACCESSIBLE_READ | GSS_S_NO_CONTEXT);
     mech = gssint_get_mechanism (ctx->mech_type);
     
     if (mech) {
index 1f8815f9d5cba06ded6620500a2360c9eaa47629..6d15e25bd74d5de3f1e7180b6f0dd870b263f170 100644 (file)
@@ -55,6 +55,7 @@ gss_name_t *dest_name;
        if (!dest_union)
                goto allocation_failure;
 
+       dest_union->loopback = 0;
        dest_union->mech_type = 0;
        dest_union->mech_name = 0;
        dest_union->name_type = 0;
@@ -92,6 +93,7 @@ gss_name_t *dest_name;
        }
 
 
+       dest_union->loopback = dest_union;
        *dest_name = (gss_name_t)dest_union;
        return (GSS_S_COMPLETE);
 
index c9c48dce06956c8d03e27c7eb1b890364f145643..1331862dc9613cf81fc3f0f7a4ecf1aabd566f84 100644 (file)
@@ -492,6 +492,7 @@ OM_uint32 gssint_convert_name_to_union_name(minor_status, mech,
     if (major_status != GSS_S_COMPLETE)
        goto allocation_failure;
 
+    union_name->loopback = union_name;
     *external_name = /*(gss_name_t) CHECK */union_name;
     return (GSS_S_COMPLETE);
 
index 48815b3615accde9acb860abedb86986ba67aad7..a82aaaf5a5031e31c5db43cac204f1f3c39b1f88 100644 (file)
@@ -78,6 +78,7 @@ gss_name_t *          output_name;
     if (!union_name)
        return (GSS_S_FAILURE);
 
+    union_name->loopback = 0;
     union_name->mech_type = 0;
     union_name->mech_name = 0;
     union_name->name_type = 0;
@@ -121,6 +122,7 @@ gss_name_t *                output_name;
            goto allocation_failure;
     }
 
+    union_name->loopback = union_name;
     *output_name = (gss_name_t)union_name;
     return (GSS_S_COMPLETE);
 
index 533b0175c0f66a43be9621aa6b1cf268d63c1ca5..b316f8199d840479ffae9c98bb6aa4fb3219edf8 100644 (file)
@@ -118,6 +118,7 @@ gss_ctx_id_t *              context_handle;
                                          &token, &ctx->internal_ctx_id);
 
     if (status == GSS_S_COMPLETE) {
+       ctx->loopback = ctx;
        *context_handle = ctx;
        return (GSS_S_COMPLETE);
     }
index f5937fe8eeab488908675b69b1faf36b53170587..65c6d05b2d82084f6ee019f46dfc673c66f2d010 100644 (file)
@@ -197,8 +197,10 @@ OM_uint32 *                time_rec;
            free(union_ctx_id->mech_type);
            free(union_ctx_id);
        }
-    } else if (*context_handle == GSS_C_NO_CONTEXT)
+    } else if (*context_handle == GSS_C_NO_CONTEXT) {
+       union_ctx_id->loopback = union_ctx_id;
        *context_handle = (gss_ctx_id_t)union_ctx_id;
+    }
 
 end:
     if (union_name->mech_name == NULL ||
index ffcce2d7e1a74144fe8db2e35eded720c2f273df..6f58d6592af2a1926840c7a1085d46cbc37d9150 100644 (file)
@@ -60,6 +60,8 @@ gss_cred_id_t *               cred_handle;
      */
     
     union_cred = (gss_union_cred_t) *cred_handle;
+    if (GSSINT_CHK_LOOP(union_cred))
+       return (GSS_S_NO_CRED | GSS_S_CALL_INACCESSIBLE_READ);
     *cred_handle = NULL;
 
     if (union_cred == (gss_union_cred_t)GSS_C_NO_CREDENTIAL)
index ff3c4a10a60cc8ed9221ce52bd551da5186a7dbd..a6615b707537e5cc296608d0bd15f541893fabb1 100644 (file)
@@ -60,6 +60,8 @@ gss_name_t *          input_name;
      */
     
     union_name = (gss_union_name_t) *input_name;
+    if (GSSINT_CHK_LOOP(union_name))
+       return (GSS_S_CALL_INACCESSIBLE_READ | GSS_S_BAD_NAME);
     *input_name = 0;
     *minor_status = 0;
 
index 07ef7109ea4bf8b1981592443cafc3adde8f7c8d..70da996d1684962a7ab8f121c6434142035b0818 100644 (file)
@@ -27,6 +27,7 @@ do {                                                          \
  * Array of context IDs typed by mechanism OID
  */
 typedef struct gss_ctx_id_struct {
+       struct gss_ctx_id_struct *loopback;
        gss_OID                 mech_type;
        gss_ctx_id_t            internal_ctx_id;
 } gss_union_ctx_id_desc, *gss_union_ctx_id_t;
@@ -36,6 +37,7 @@ typedef struct gss_ctx_id_struct {
  * mechanism specific name....
  */
 typedef struct gss_name_struct {
+       struct gss_name_struct *loopback;
        gss_OID                 name_type;
        gss_buffer_t            external_name;
        /*
@@ -70,12 +72,22 @@ typedef struct gss_union_cred_auxinfo {
  * Set of Credentials typed on mechanism OID
  */
 typedef struct gss_cred_id_struct {
+       struct gss_cred_id_struct *loopback;
        int                     count;
        gss_OID                 mechs_array;
        gss_cred_id_t           *cred_array;
        gss_union_cred_auxinfo  auxinfo;
 } gss_union_cred_desc, *gss_union_cred_t;
  
+/*
+ * Rudimentary pointer validation macro to check whether the
+ * "loopback" field of an opaque struct points back to itself.  This
+ * field also catches some programming errors where an opaque pointer
+ * is passed to a function expecting the address of the opaque
+ * pointer.
+ */
+#define GSSINT_CHK_LOOP(p) (!((p) != NULL && (p)->loopback == (p)))
+
 /********************************************************/
 /* The Mechanism Dispatch Table -- a mechanism needs to */
 /* define one of these and provide a function to return */