From c76c0951a9b66600a07967289fb0cc74c1333865 Mon Sep 17 00:00:00 2001 From: Rich Megginson Date: Mon, 16 Feb 2009 22:40:13 +0000 Subject: Resolves: bug 481052 Bug Description: some cn=config options show up with incorrect value on 64-bit Reviewed by: nkinder (Thanks!) Fix Description: The get functions return a specific sized type (e.g. an int). We were assigning this to a void *. We cannot do this. We must assign the return value from the get function to the correct size and type variable. I changed the config code to do this. I also had a look at the database and chaining database config code which does similar things with void *, but that code works a little bit differently and appears to be ok. Platforms tested: RHEL5 x86_64 (need to test on HP-UX) Flag Day: no Doc impact: no --- ldap/servers/plugins/chainingdb/cb_instance.c | 2 +- ldap/servers/slapd/libglobs.c | 33 +++++++++++++++++++++------ 2 files changed, 27 insertions(+), 8 deletions(-) (limited to 'ldap/servers') diff --git a/ldap/servers/plugins/chainingdb/cb_instance.c b/ldap/servers/plugins/chainingdb/cb_instance.c index 19c05bab..f813cec0 100644 --- a/ldap/servers/plugins/chainingdb/cb_instance.c +++ b/ldap/servers/plugins/chainingdb/cb_instance.c @@ -1546,7 +1546,7 @@ void cb_instance_config_get(void *arg, cb_instance_config_info *config, char *bu sprintf(buf, "%o", (int) ((uintptr_t)config->config_get_fn(arg))); break; case CB_CONFIG_TYPE_LONG: - sprintf(buf, "%ld", (long) config->config_get_fn(arg)); + sprintf(buf, "%ld", (long) ((uintptr_t)config->config_get_fn(arg))); break; case CB_CONFIG_TYPE_STRING: /* Remember the get function for strings returns memory diff --git a/ldap/servers/slapd/libglobs.c b/ldap/servers/slapd/libglobs.c index ae476630..e473663c 100644 --- a/ldap/servers/slapd/libglobs.c +++ b/ldap/servers/slapd/libglobs.c @@ -130,6 +130,12 @@ isIntegralType(ConfigVarType type) return type == CONFIG_INT || type == CONFIG_LONG || type == CONFIG_ON_OFF; } +static int +isInt(ConfigVarType type) +{ + return type == CONFIG_INT || type == CONFIG_ON_OFF || type == CONFIG_SPECIAL_SSLCLIENTAUTH || type == CONFIG_SPECIAL_ERRORLOGLEVEL; +} + /* the caller will typically have to cast the result based on the ConfigVarType */ typedef void *(*ConfigGetFunc)(void); @@ -5459,8 +5465,10 @@ config_set_entry(Slapi_Entry *e) */ for (ii = 0; ii < tablesize; ++ii) { struct config_get_and_set *cgas = &ConfigList[ii]; - void **value = 0; - void *alloc_val; + int ival = 0; + long lval = 0; + void **value = NULL; + void *alloc_val = NULL; int needs_free = 0; PR_ASSERT(cgas); @@ -5472,19 +5480,30 @@ config_set_entry(Slapi_Entry *e) continue; } - alloc_val = (cgas->getfunc)(); - - value = &alloc_val; /* value must be address of pointer */ - if (!isIntegralType(cgas->config_var_type)) + /* must cast return of getfunc and store in variable of correct sized type */ + /* otherwise endianness problems will ensue */ + if (isInt(cgas->config_var_type)) { + ival = (int)(intptr_t)(cgas->getfunc)(); + value = (void **)&ival; /* value must be address of int */ + } else if (cgas->config_var_type == CONFIG_LONG) { + lval = (long)(intptr_t)(cgas->getfunc)(); + value = (void **)&lval; /* value must be address of long */ + } else { + alloc_val = (cgas->getfunc)(); + value = &alloc_val; /* value must be address of pointer */ needs_free = 1; /* get funcs must return alloc'd memory except for get funcs which return a simple integral type e.g. int */ + } config_set_value(e, cgas, value); if (needs_free && value) { /* assumes memory allocated by slapi_ch_Xalloc */ if (CONFIG_CHARRAY == cgas->config_var_type) { charray_free(*((char ***)value)); - } else { + } else if (CONFIG_SPECIAL_REFERRALLIST == cgas->config_var_type) { + ber_bvecfree(*((struct berval ***)value)); + } else if ((CONFIG_CONSTANT_INT != cgas->config_var_type) && /* do not free constants */ + (CONFIG_CONSTANT_STRING != cgas->config_var_type)) { slapi_ch_free(value); } } -- cgit