Questions about iter check in profile_iterator()
Will Fiveash
will.fiveash at oracle.com
Mon Jan 12 20:13:50 EST 2015
On Mon, Jan 12, 2015 at 04:06:40PM -0800, Neng Xue wrote:
> Hi MIT krb team,
>
> Recently I am working on a kerberos related project in Solaris which will
> upgrade our krb version to 1.13. We have a set of solaris specific profile
> interfaces underneath using MIT kerberos profile interfaces. They used to
> work fine. However, after the version upgrade I noticed the interface
> wrapper encountered an issue. I narrowed down the issue to:
>
> *prof_get.c:profile_iterator()*:
>
> 582 if (iter->magic != PROF_MAGIC_ITERATOR)
> 583 return PROF_MAGIC_ITERATOR;
>
> When the iter is NULL our program will segmentation fault because of the
> null pointer deference.
>
> Here is piece of our code:
>
> code = *profile_iterator_create*(profile, hierarchy,
> 42 PROFILE_ITER_LIST_SECTION, *&state*);
> 43 while (code == 0) {
> 44 code = *profile_iterator*(&*state*, &name, &value);
> 45 if (code == 0 && name != NULL) {
> 46
> 47 if (key != NULL && value != NULL) {
> 48 boolean_t ex_match = strcmp(key, value) ?
> 49 B_FALSE : B_TRUE;
> 50 boolean_t match = strcasecmp(key, value) ?
> 51 B_FALSE : B_TRUE;
> 52
> 53 if (ex_match == B_FALSE && case_ins == B_TRUE &&
> 54 match == B_TRUE) {
> 55 code2 = add_to_list(&values, name);
> 56 if (code2 != 0) {
> 57 end_list(&values, 0);
> 58 code = code2;
> 59 } else
> 60 end_list(&values, &ret_values);
> 61 goto cleanup;
> 62 } else if (ex_match == B_FALSE ||
> 63 case_ins == B_TRUE)
> 64 goto not_found;
> 65 }
> 66 code2 = add_to_list(&values, name);
> 67 if (code2 != 0) {
> 68 end_list(&values, 0);
> 69 code = code2;
> 70 goto cleanup;
> 71 }
> 72 found = B_TRUE;
> 73 }
> 74
> 75not_found:
> 76 if (name != NULL) {
> 77 profile_release_string(name);
> 78 name = NULL;
> 79 }
> 80 if (value != NULL) {
> 81 profile_release_string(value);
> 82 value = NULL;
> 83 }
> 84 }
>
> The while loop will segmentation fault during the *third* loop. During the
> *second* loop, *profile_node_iterator()* underneath will free the iter
> pointer, then the third loop will still use that iter pointer to deference
> iter->magic value. So my question is that do we use the profile_iterator()
> in the wrong way or there should be an iter check in the profile_iterator()?
> Thanks.
Given what Neng has told me it looks like profile_iterator() is
returning 0 when iter->idata is NULL just after the call to
profile_node_iterator() which leads to (in profile_iterator):
retval = profile_node_iterator(&iter->idata, 0, &name, &value);
if (iter->idata == NULL) { <----
free(iter); <----
*iter_p = NULL; <----
}
Also there is the call to profile_node_iterator() and in the definition
of profile_node_iterator() I see:
errcode_t profile_node_iterator(void **iter_p, <--------
struct profile_node **ret_node,
char **ret_name, char **ret_value)
So in the profile_iterator call to profile_node_iterator() the
&iter->idata arg is iter_p for profile_node_iterator? Seems odd to me.
--
Will Fiveash
Oracle Solaris Software Engineer
More information about the krbdev
mailing list