ldap/servers/slapd/back-ldbm/dblayer.c | 2
ldap/servers/slapd/back-ldbm/ldbm_config.c | 50 +++++++++++++++-----
ldap/servers/slapd/back-ldbm/ldbm_instance_config.c | 16 ++++++
3 files changed, 55 insertions(+), 13 deletions(-)
New commits:
commit 1e035d1111f6abcb87e760a2b9e41fa9e05a7ebd
Author: Mark Reynolds <mreynolds(a)redhat.com>
Date: Tue Oct 8 17:16:23 2013 -0400
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);
}