From aee7b9d0852e8c217c26c29aa22ef766a8e4b7d7 Mon Sep 17 00:00:00 2001 From: Mark Reynolds Date: Jul 10 2013 19:54:11 +0000 Subject: Ticket 47427 - Overflow in nsslapd-disk-monitoring-threshold Bug Description: The threshold setting was being stored as an "int" instead of a PRUint64. Config setting validation was also incomplete. Fix Description: Changed the data type to PRUint64 from int, and improved the config validation, and logging. https://fedorahosted.org/389/ticket/47427 Reviewed by: richm & nhosoi(Thanks!!) (cherry picked from commit 6a0ed40b25a6dd4aaf3774a70199e8842499b42d) --- diff --git a/ldap/servers/slapd/daemon.c b/ldap/servers/slapd/daemon.c index a745b6d..5a1705d 100644 --- a/ldap/servers/slapd/daemon.c +++ b/ldap/servers/slapd/daemon.c @@ -641,16 +641,16 @@ disk_mon_get_dirs(char ***list, int logs_critical){ * directory. */ char * -disk_mon_check_diskspace(char **dirs, PRInt64 threshold, PRInt64 *disk_space) +disk_mon_check_diskspace(char **dirs, PRUint64 threshold, PRUint64 *disk_space) { #ifdef LINUX struct statfs buf; #else struct statvfs buf; #endif - PRInt64 worst_disk_space = threshold; - PRInt64 freeBytes = 0; - PRInt64 blockSize = 0; + PRUint64 worst_disk_space = threshold; + PRUint64 freeBytes = 0; + PRUint64 blockSize = 0; char *worst_dir = NULL; int hit_threshold = 0; int i = 0; @@ -707,10 +707,10 @@ disk_monitoring_thread(void *nothing) char errorbuf[BUFSIZ]; char **dirs = NULL; char *dirstr = NULL; - PRInt64 previous_mark = 0; - PRInt64 disk_space = 0; - PRInt64 threshold = 0; - PRInt64 halfway = 0; + PRUint64 previous_mark = 0; + PRUint64 disk_space = 0; + PRUint64 threshold = 0; + PRUint64 halfway = 0; time_t start = 0; time_t now = 0; int deleted_rotated_logs = 0; @@ -792,7 +792,7 @@ disk_monitoring_thread(void *nothing) * Check if we are already critical */ if(disk_space < 4096){ /* 4 k */ - LDAPDebug(LDAP_DEBUG_ANY, "Disk space is critically low on disk (%s), remaining space: %d Kb. " + LDAPDebug(LDAP_DEBUG_ANY, "Disk space is critically low on disk (%s), remaining space: %" NSPRIu64 " Kb. " "Signaling slapd for shutdown...\n", dirstr , (disk_space / 1024), 0); g_set_shutdown( SLAPI_SHUTDOWN_EXIT ); return; @@ -802,7 +802,7 @@ disk_monitoring_thread(void *nothing) * if logging is not critical */ if(verbose_logging != 0 && verbose_logging != LDAP_DEBUG_ANY){ - LDAPDebug(LDAP_DEBUG_ANY, "Disk space is low on disk (%s), remaining space: %d Kb, " + LDAPDebug(LDAP_DEBUG_ANY, "Disk space is low on disk (%s), remaining space: %" NSPRIu64 " Kb, " "temporarily setting error loglevel to zero.\n", dirstr, (disk_space / 1024), 0); /* Setting the log level back to zero, actually sets the value to LDAP_DEBUG_ANY */ @@ -814,11 +814,11 @@ disk_monitoring_thread(void *nothing) * access/audit logs, log another error, and continue. */ if(!logs_disabled && !logging_critical){ - LDAPDebug(LDAP_DEBUG_ANY, "Disk space is too low on disk (%s), remaining space: %d Kb, " - "disabling access and audit logging.\n", dirstr, (disk_space / 1024), 0); - config_set_accesslog_enabled(LOGGING_OFF); - config_set_auditlog_enabled(LOGGING_OFF); - logs_disabled = 1; + LDAPDebug(LDAP_DEBUG_ANY, "Disk space is too low on disk (%s), remaining space: %" NSPRIu64 " Kb, " + "disabling access and audit logging.\n", dirstr, (disk_space / 1024), 0); + config_set_accesslog_enabled(LOGGING_OFF); + config_set_auditlog_enabled(LOGGING_OFF); + logs_disabled = 1; continue; } /* @@ -826,17 +826,17 @@ disk_monitoring_thread(void *nothing) * access/audit logging, then delete the rotated logs, log another error, and continue. */ if(!deleted_rotated_logs && !logging_critical){ - LDAPDebug(LDAP_DEBUG_ANY, "Disk space is too low on disk (%s), remaining space: %d Kb, " - "deleting rotated logs.\n", dirstr, (disk_space / 1024), 0); - log__delete_rotated_logs(); - deleted_rotated_logs = 1; + LDAPDebug(LDAP_DEBUG_ANY, "Disk space is too low on disk (%s), remaining space: %" NSPRIu64 " Kb, " + "deleting rotated logs.\n", dirstr, (disk_space / 1024), 0); + log__delete_rotated_logs(); + deleted_rotated_logs = 1; continue; } /* * Ok, we've done what we can, log a message if we continue to lose available disk space */ if(disk_space < previous_mark){ - LDAPDebug(LDAP_DEBUG_ANY, "Disk space is too low on disk (%s), remaining space: %d Kb\n", + LDAPDebug(LDAP_DEBUG_ANY, "Disk space is too low on disk (%s), remaining space: %" NSPRIu64 " Kb\n", dirstr, (disk_space / 1024), 0); } /* @@ -848,7 +848,7 @@ disk_monitoring_thread(void *nothing) * */ if(disk_space < halfway){ - LDAPDebug(LDAP_DEBUG_ANY, "Disk space on (%s) is too far below the threshold(%d bytes). " + LDAPDebug(LDAP_DEBUG_ANY, "Disk space on (%s) is too far below the threshold(%" NSPRIu64 " bytes). " "Waiting %d minutes for disk space to be cleaned up before shutting slapd down...\n", dirstr, threshold, (grace_period / 60)); time(&start); @@ -870,7 +870,7 @@ disk_monitoring_thread(void *nothing) /* * Excellent, we are back to acceptable levels, reset everything... */ - LDAPDebug(LDAP_DEBUG_ANY, "Available disk space is now acceptable (%d bytes). Aborting" + LDAPDebug(LDAP_DEBUG_ANY, "Available disk space is now acceptable (%" NSPRIu64 " bytes). Aborting" " shutdown, and restoring the log settings.\n",disk_space,0,0); if(logs_disabled && using_accesslog){ config_set_accesslog_enabled(LOGGING_ON); @@ -890,7 +890,7 @@ disk_monitoring_thread(void *nothing) /* * Disk space is critical, log an error, and shut it down now! */ - LDAPDebug(LDAP_DEBUG_ANY, "Disk space is critically low on disk (%s), remaining space: %d Kb." + LDAPDebug(LDAP_DEBUG_ANY, "Disk space is critically low on disk (%s), remaining space: %" NSPRIu64 " Kb." " Signaling slapd for shutdown...\n", dirstr, (disk_space / 1024), 0); g_set_shutdown( SLAPI_SHUTDOWN_DISKFULL ); return; @@ -907,7 +907,7 @@ disk_monitoring_thread(void *nothing) /* * If disk space was freed up we would of detected in the above while loop. So shut it down. */ - LDAPDebug(LDAP_DEBUG_ANY, "Disk space is still too low (%d Kb). Signaling slapd for shutdown...\n", + LDAPDebug(LDAP_DEBUG_ANY, "Disk space is still too low (%" NSPRIu64 " Kb). Signaling slapd for shutdown...\n", (disk_space / 1024), 0, 0); g_set_shutdown( SLAPI_SHUTDOWN_DISKFULL ); diff --git a/ldap/servers/slapd/libglobs.c b/ldap/servers/slapd/libglobs.c index dbdf5c2..c294eea 100644 --- a/ldap/servers/slapd/libglobs.c +++ b/ldap/servers/slapd/libglobs.c @@ -1650,17 +1650,19 @@ config_set_disk_threshold( const char *attrname, char *value, char *errorbuf, in { slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); int retVal = LDAP_SUCCESS; - long threshold = 0; + PRUint64 threshold = 0; char *endp = NULL; if ( config_value_is_null( attrname, value, errorbuf, 0 )) { return LDAP_OPERATIONS_ERROR; } - threshold = strtol(value, &endp, 10); + errno = 0; + threshold = strtoll(value, &endp, 10); - if ( *endp != '\0' || threshold < 2048 ) { - PR_snprintf ( errorbuf, SLAPI_DSE_RETURNTEXT_SIZE, "%s: \"%s\" is invalid, threshold must be greater than 2048 and less then %ld", + if ( *endp != '\0' || threshold <= 4096 || errno == ERANGE ) { + PR_snprintf ( errorbuf, SLAPI_DSE_RETURNTEXT_SIZE, + "%s: \"%s\" is invalid, threshold must be greater than 4096 and less then %llu", attrname, value, LONG_MAX ); retVal = LDAP_OPERATIONS_ERROR; return retVal; @@ -4320,7 +4322,7 @@ config_get_disk_grace_period(){ return retVal; } -long +PRUint64 config_get_disk_threshold(){ slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); long retVal; diff --git a/ldap/servers/slapd/proto-slap.h b/ldap/servers/slapd/proto-slap.h index ad4b87a..52d5aee 100644 --- a/ldap/servers/slapd/proto-slap.h +++ b/ldap/servers/slapd/proto-slap.h @@ -553,7 +553,7 @@ void config_set_accesslog_enabled(int value); void config_set_auditlog_enabled(int value); int config_get_accesslog_logging_enabled(); int config_get_disk_monitoring(); -long config_get_disk_threshold(); +PRUint64 config_get_disk_threshold(); int config_get_disk_grace_period(); int config_get_disk_logging_critical(); int config_get_ndn_cache_count(); diff --git a/ldap/servers/slapd/slap.h b/ldap/servers/slapd/slap.h index 1420316..7e38d26 100644 --- a/ldap/servers/slapd/slap.h +++ b/ldap/servers/slapd/slap.h @@ -2314,7 +2314,7 @@ typedef struct _slapdFrontendConfig { /* disk monitoring */ slapi_onoff_t disk_monitoring; - int disk_threshold; + PRUint64 disk_threshold; int disk_grace_period; slapi_onoff_t disk_logging_critical;