Explorar o código

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

Rich Megginson %!s(int64=17) %!d(string=hai) anos
pai
achega
c76c0951a9

+ 1 - 1
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

+ 26 - 7
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);
             }
         }