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
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,
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,
/* 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++) {
*time_rec = outTime;
+ creds->loopback = creds;
*output_cred_handle = (gss_cred_id_t)creds;
return (GSS_S_COMPLETE);
}
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. */
*/
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) {
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;
}
+ dest_union->loopback = dest_union;
*dest_name = (gss_name_t)dest_union;
return (GSS_S_COMPLETE);
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);
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;
goto allocation_failure;
}
+ union_name->loopback = union_name;
*output_name = (gss_name_t)union_name;
return (GSS_S_COMPLETE);
&token, &ctx->internal_ctx_id);
if (status == GSS_S_COMPLETE) {
+ ctx->loopback = ctx;
*context_handle = ctx;
return (GSS_S_COMPLETE);
}
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 ||
*/
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)
*/
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;
* 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;
* mechanism specific name....
*/
typedef struct gss_name_struct {
+ struct gss_name_struct *loopback;
gss_OID name_type;
gss_buffer_t external_name;
/*
* 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 */