From 1e035d1111f6abcb87e760a2b9e41fa9e05a7ebd Mon Sep 17 00:00:00 2001 From: Mark Reynolds Date: Oct 09 2013 14:28:32 +0000 Subject: Ticket 47499 - if nsslapd-cachememsize set to the number larger than the RAM available, should result in proper error message. Bug Description: The server allows any value to be set for all the cache sizes. If this value is too large it will basically crash the server. Fix Description: Do a value verification before allowing the change. Report an error 53 and a descriptive error string if the value is too large. https://fedorahosted.org/389/ticket/47499 Reviewed by: nhosoi(Thanks!!) --- diff --git a/ldap/servers/slapd/back-ldbm/dblayer.c b/ldap/servers/slapd/back-ldbm/dblayer.c index 3b4a536..62a2bda 100644 --- a/ldap/servers/slapd/back-ldbm/dblayer.c +++ b/ldap/servers/slapd/back-ldbm/dblayer.c @@ -1112,7 +1112,7 @@ int dblayer_is_cachesize_sane(size_t *cachesize) * after the current working set size for this process has been subtracted, * then we say that's insane and try to correct. */ - issane = (int)(*cachesize / pagesize) <= (pages - procpages); + issane = (int)((*cachesize / pagesize) <= (pages - procpages)); if (!issane) { *cachesize = (size_t)((pages - procpages) * pagesize); } diff --git a/ldap/servers/slapd/back-ldbm/ldbm_config.c b/ldap/servers/slapd/back-ldbm/ldbm_config.c index d53e9b3..3bb0371 100644 --- a/ldap/servers/slapd/back-ldbm/ldbm_config.c +++ b/ldap/servers/slapd/back-ldbm/ldbm_config.c @@ -430,25 +430,31 @@ static int ldbm_config_dbcachesize_set(void *arg, void *value, char *errorbuf, i { struct ldbminfo *li = (struct ldbminfo *) arg; int retval = LDAP_SUCCESS; - size_t val = (size_t) value; + size_t val = (size_t)value; if (apply) { /* Stop the user configuring a stupidly small cache */ /* min: 8KB (page size) * def thrd cnts (threadnumber==20). */ #define DBDEFMINSIZ 500000 if (val < DBDEFMINSIZ) { - LDAPDebug( LDAP_DEBUG_ANY,"WARNING: cache too small, increasing to %dK bytes\n", DBDEFMINSIZ/1000, 0, 0); + LDAPDebug( LDAP_DEBUG_ANY,"WARNING: cache too small, increasing to %dK bytes\n", + DBDEFMINSIZ/1000, 0, 0); val = DBDEFMINSIZ; - } - + } else if (!dblayer_is_cachesize_sane(&val)){ + PR_snprintf(errorbuf, SLAPI_DSE_RETURNTEXT_SIZE, + "Error: dbcachememsize value is too large."); + LDAPDebug( LDAP_DEBUG_ANY,"Error: dbcachememsize value is too large.\n", + 0, 0, 0); + return LDAP_UNWILLING_TO_PERFORM; + } if (CONFIG_PHASE_RUNNING == phase) { li->li_new_dbcachesize = val; - LDAPDebug(LDAP_DEBUG_ANY, "New db cache size will not take affect until the server is restarted\n", 0, 0, 0); + LDAPDebug(LDAP_DEBUG_ANY, "New db cache size will not take affect until the server is restarted\n", + 0, 0, 0); } else { li->li_new_dbcachesize = val; li->li_dbcachesize = val; } - } return retval; @@ -491,13 +497,20 @@ static int ldbm_config_dbncache_set(void *arg, void *value, char *errorbuf, int { struct ldbminfo *li = (struct ldbminfo *) arg; int retval = LDAP_SUCCESS; - int val = (int) ((uintptr_t)value); + size_t val = (size_t) ((uintptr_t)value); if (apply) { if (val < 0) { LDAPDebug( LDAP_DEBUG_ANY,"WARNING: ncache will not take negative value\n", 0, 0, 0); val = 0; } + if (!dblayer_is_cachesize_sane(&val)){ + PR_snprintf(errorbuf, SLAPI_DSE_RETURNTEXT_SIZE, + "Error: dbncache size value is too large."); + LDAPDebug( LDAP_DEBUG_ANY,"Error: dbncache size value is too large.\n", + val, 0, 0); + return LDAP_UNWILLING_TO_PERFORM; + } if (CONFIG_PHASE_RUNNING == phase) { li->li_new_dbncache = val; @@ -1056,9 +1069,16 @@ static int ldbm_config_db_cache_set(void *arg, void *value, char *errorbuf, int { struct ldbminfo *li = (struct ldbminfo *) arg; int retval = LDAP_SUCCESS; - int val = (int) ((uintptr_t)value); + size_t val = (size_t) ((uintptr_t)value); if (apply) { + if (!dblayer_is_cachesize_sane(&val)){ + PR_snprintf(errorbuf, SLAPI_DSE_RETURNTEXT_SIZE, + "Error: db cachesize value is too large"); + LDAPDebug( LDAP_DEBUG_ANY,"Error: db cachesize value is too large.\n", + val, 0, 0); + return LDAP_UNWILLING_TO_PERFORM; + } li->li_dblayer_private->dblayer_cache_config = val; } @@ -1170,9 +1190,17 @@ static int ldbm_config_import_cachesize_set(void *arg, void *value, char *errorb int phase, int apply) { struct ldbminfo *li = (struct ldbminfo *)arg; - - if (apply) - li->li_import_cachesize = (size_t)value; + size_t val = (size_t)value; + if (apply){ + if (!dblayer_is_cachesize_sane(&val)){ + PR_snprintf(errorbuf, SLAPI_DSE_RETURNTEXT_SIZE, + "Error: import cachesize value is too large."); + LDAPDebug( LDAP_DEBUG_ANY,"Error: import cachesize value is too large.\n", + 0, 0, 0); + return LDAP_UNWILLING_TO_PERFORM; + } + li->li_import_cachesize = val; + } return LDAP_SUCCESS; } diff --git a/ldap/servers/slapd/back-ldbm/ldbm_instance_config.c b/ldap/servers/slapd/back-ldbm/ldbm_instance_config.c index 34d9bf5..565e9ad 100644 --- a/ldap/servers/slapd/back-ldbm/ldbm_instance_config.c +++ b/ldap/servers/slapd/back-ldbm/ldbm_instance_config.c @@ -125,6 +125,13 @@ ldbm_instance_config_cachememsize_set(void *arg, void *value, char *errorbuf, in /* Do whatever we can to make sure the data is ok. */ if (apply) { + if (!dblayer_is_cachesize_sane(&val)){ + PR_snprintf(errorbuf, SLAPI_DSE_RETURNTEXT_SIZE, + "Error: cachememsize value is too large."); + LDAPDebug( LDAP_DEBUG_ANY,"Error: cachememsize value is too large.\n", + 0, 0, 0); + return LDAP_UNWILLING_TO_PERFORM; + } cache_set_max_size(&(inst->inst_cache), val, CACHE_TYPE_ENTRY); } @@ -144,11 +151,18 @@ ldbm_instance_config_dncachememsize_set(void *arg, void *value, char *errorbuf, { ldbm_instance *inst = (ldbm_instance *) arg; int retval = LDAP_SUCCESS; - size_t val = (size_t) value; + size_t val = (size_t)value; /* Do whatever we can to make sure the data is ok. */ if (apply) { + if (!dblayer_is_cachesize_sane(&val)){ + PR_snprintf(errorbuf, SLAPI_DSE_RETURNTEXT_SIZE, + "Error: dncachememsize value is too large."); + LDAPDebug( LDAP_DEBUG_ANY,"Error: dncachememsize value is too large.\n", + 0, 0, 0); + return LDAP_UNWILLING_TO_PERFORM; + } cache_set_max_size(&(inst->inst_dncache), val, CACHE_TYPE_DN); }