From 653af4acb1d0431063b6eb8e7deb49ea249936a2 Mon Sep 17 00:00:00 2001 From: luckky Date: Mon, 16 Dec 2024 17:21:59 +0800 Subject: [PATCH] set to default when param is overflow --- ...et-to-default-when-param-is-overflow.patch | 136 ++++++++++++++++++ rasdaemon.spec | 9 +- 2 files changed, 144 insertions(+), 1 deletion(-) create mode 100644 bugfix-set-to-default-when-param-is-overflow.patch diff --git a/bugfix-set-to-default-when-param-is-overflow.patch b/bugfix-set-to-default-when-param-is-overflow.patch new file mode 100644 index 0000000..79199b5 --- /dev/null +++ b/bugfix-set-to-default-when-param-is-overflow.patch @@ -0,0 +1,136 @@ +From c306d693f86cd9e128a103b1670b653613eb78d2 Mon Sep 17 00:00:00 2001 +From: luckky +Date: Mon, 16 Dec 2024 17:20:04 +0800 +Subject: [PATCH] bugfix set to default when param is overflow +1. In this patch, we check if the value is overflow before parsing the + value with its unit. we replaced sscanf with strtoul cause the strtoul + has clear errno ERANGE for overflow case. +2. When the value is overflow, the sscanf will produce Undefined Behavior + (https://man7.org/linux/man-pages/man3/sscanf.3.html#BUGS). + The final value after being truncated is confusing. So in this patch + we will set to default value when the value is overflow. + +--- + ras-page-isolation.c | 56 +++++++++++++++++++++++++++----------------- + 1 file changed, 35 insertions(+), 21 deletions(-) + +diff --git a/ras-page-isolation.c b/ras-page-isolation.c +index caa8c31..ed07b70 100644 +--- a/ras-page-isolation.c ++++ b/ras-page-isolation.c +@@ -44,6 +44,7 @@ static struct isolation threshold = { + .units = threshold_units, + .env = "50", + .unit = "", ++ .val = 50, + }; + + static struct isolation cycle = { +@@ -51,6 +52,7 @@ static struct isolation cycle = { + .units = cycle_units, + .env = "24h", + .unit = "h", ++ .val = 86400, + }; + + static const char *kernel_offline[] = { +@@ -106,10 +108,24 @@ static void page_offline_init(void) + offline_choice[offline].name); + } + ++/* ++ * The 'parse_isolation_env' will parse the real value from the env settings ++ * in config file. The valid format of the env is pure positive number ++ * (like '12345') or a positive number with specific units (like '24h'). ++ * When the unit is not set, we use the default unit (threshold for '' and ++ * cycle for 'h'). ++ * The number is only supported in decimal, while others will produce errors. ++ * This function will parse the high level units to base units (like 'h' is ++ * a high level unit and 's' is a base unit). ++ * The valid value range is [1, UNLONG_MAX], and when the value is out of ++ * range (whether the origin pure number without units or the parsed number ++ * with the base units), the value will be set to the default value. ++ */ + static void parse_isolation_env(struct isolation *config) + { + char *env = getenv(config->name); + char *unit = NULL; ++ char *endptr = NULL; + const struct config *units = NULL; + int i, no_unit; + int valid = 0; +@@ -146,43 +162,41 @@ static void parse_isolation_env(struct isolation *config) + parse: + /* if invalid, use default env */ + if (valid) { +- config->env = env; + if (!no_unit) + config->unit = unit; + } else { ++ env = config->env; + log(TERM, LOG_INFO, "Improper %s, set to default %s.\n", + config->name, config->env); + } + + /* if env value string is greater than ulong_max, truncate the last digit */ +- sscanf(config->env, "%lu", &value); ++ errno = 0; ++ value = strtoul(env, &endptr, 10); ++ if (errno == ERANGE) ++ config->overflow = true; + for (units = config->units; units->name; units++) { + if (!strcasecmp(config->unit, units->name)) + unit_matched = 1; + if (unit_matched) { + tmp = value; + value *= units->val; +- if (tmp != 0 && value / tmp != units->val) ++ if (tmp != 0 && value / tmp != units->val) { + config->overflow = true; ++ break; ++ } + } + } +- config->val = value; +- /* In order to output value and unit perfectly */ +- config->unit = no_unit ? config->unit : ""; +-} +- +-static void parse_env_string(struct isolation *config, char *str, unsigned int size) +-{ +- int i; +- +- if (config->overflow) { +- /* when overflow, use basic unit */ +- for (i = 0; config->units[i].name; i++) ; +- snprintf(str, size, "%lu%s", config->val, config->units[i-1].name); +- log(TERM, LOG_INFO, "%s is set overflow(%s), truncate it\n", +- config->name, config->env); ++ if (!config->overflow) { ++ config->val = value; ++ config->env = env; ++ /* In order to output value and unit perfectly */ ++ config->unit = no_unit ? config->unit : ""; + } else { +- snprintf(str, size, "%s%s", config->env, config->unit); ++ log(TERM, LOG_INFO, "%s is set overflow(%s), set to default %s\n", ++ config->name, env, config->env); ++ /* In order to output value and unit perfectly */ ++ config->unit = ""; + } + } + +@@ -199,8 +213,8 @@ static void page_isolation_init(void) + + parse_isolation_env(&threshold); + parse_isolation_env(&cycle); +- parse_env_string(&threshold, threshold_string, sizeof(threshold_string)); +- parse_env_string(&cycle, cycle_string, sizeof(cycle_string)); ++ snprintf(threshold_string, sizeof(threshold_string), "%s%s", threshold.env, threshold.unit); ++ snprintf(cycle_string, sizeof(cycle_string), "%s%s", cycle.env, cycle.unit); + log(TERM, LOG_INFO, "Threshold of memory Corrected Errors is %s / %s\n", + threshold_string, cycle_string); + } +-- +2.43.0 + diff --git a/rasdaemon.spec b/rasdaemon.spec index 4e7cff8..dbe6a9b 100644 --- a/rasdaemon.spec +++ b/rasdaemon.spec @@ -1,6 +1,6 @@ Name: rasdaemon Version: 0.6.7 -Release: 18 +Release: 19 License: GPLv2 Summary: Utility to get Platform Reliability, Availability and Serviceability (RAS) reports via the Kernel tracing events URL: https://github.com/mchehab/rasdaemon.git @@ -56,6 +56,7 @@ Patch9000: fix-ras-mc-ctl.service-startup-failed-when-selinux-is-no.patch Patch9001: fix-ras-events-quit-loop-in-read_ras_event-when-kbuf-dat.patch Patch9002: add-dynamic-switch-of-ras-events-support-and-disable-block-rq-complete.patch Patch9003: fix-rasdaemon-print-loading-config-logs-multiple-times.patch +Patch9004: bugfix-set-to-default-when-param-is-overflow.patch %description The rasdaemon program is a daemon which monitors the platform @@ -109,6 +110,12 @@ if [ $1 -eq 0 ] ; then fi %changelog +* Mon Dec 16 2024 guodashun - 0.6.7-19 +- Type:bugfix +- ID:NA +- SUG:NA +- DESC:set to default when param is overflow + * Thu Apr 25 2024 yangjunshuo - 0.6.7-18 - Type:bugfix - ID:NA -- Gitee