[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
problem with lifetime of krb5_ccache's...
Hello,
I've had a problem with krb5_ccache structs becoming invalid if they are used
after the context struct they were created with gets freed. The problem is
that the krb5_ccache ops pointer is just a shallow copy from the context ops
array and the cache ops pointer becomes invalid when the context is freed.
I hit this problem when dealing with pam modules- if you store a memory cache
between pam calls you have problems if you try to copy that memory cache to a
file one later.
Making a deep copy in allocate_ccache in krb5/cache.c fixes the problem for
me. It seems that this should be safe to do since the problem is the ops
pointer in the krb5_ccache struct becoming invalid, but the actual data in
the krb5_cc_ops struct should be the same since it's just function pointers +
one char* anyway.
I've attached a patch that fixes the problem for me. Is this the right
approach to fix this problem?
Wynn
Index: cache.c
===================================================================
RCS file: /col/csm/cvs/VAS/src/heimdal/lib/krb5/cache.c,v
retrieving revision 1.2
diff -u -p -B -w -r1.2 cache.c
--- cache.c 2002/05/29 15:23:50 1.2
+++ cache.c 2002/05/29 17:03:54
@@ -107,11 +107,34 @@ allocate_ccache (krb5_context context,
krb5_set_error_string(context, "malloc: out of memory");
return KRB5_CC_NOMEM;
}
- p->ops = ops;
+
+ /* we make a deep copy so the ccache does not become invalid
+ when the context is free'd. krb5_cc_close free's all this
+ memory
+ */
+ p->ops = malloc(sizeof(*ops));
+ if( p->ops == NULL ) {
+ free(p);
+ krb5_set_error_string(context, "malloc: out of memory");
+ return KRB5_CC_NOMEM;
+ }
+ memcpy(p->ops, (const void*)ops, sizeof(*ops));
+ p->ops->prefix = strdup( ops->prefix );
+ if( p->ops->prefix == NULL ) {
+ free(p->ops);
+ free(p);
+ krb5_set_error_string(context, "malloc: out of memory");
+ return KRB5_CC_NOMEM;
+ }
+
*id = p;
ret = p->ops->resolve(context, id, residual);
if( ret )
+ {
+ free(p->ops->prefix);
+ free(p->ops);
free(p);
+ }
return ret;
}
@@ -265,8 +288,14 @@ krb5_cc_close(krb5_context context,
krb5_ccache id)
{
krb5_error_code ret;
+
ret = id->ops->close(context, id);
+
+ /* free all the memory since it was a deep copy */
+ free(id->ops->prefix);
+ free(id->ops);
free(id);
+
return ret;
}