From ac1b9fc80b0fba5412cb603abb4ccbfd09bc1f7c Mon Sep 17 00:00:00 2001 From: Sang Woo Kim Date: Sun, 19 Jul 2026 17:38:55 +0900 Subject: [PATCH] udpiiu: reject a non-finite or non-positive EPICS_CA_MAX_SEARCH_PERIOD epicsScanDouble accepts "inf" and "nan", so envGetDoubleConfigParam returns success for them and the parsed value flows into getMaxPeriod's only range gate, maxPeriod < maxSearchPeriodLowerLimit. That comparison is false for both inf and NaN, so a non-finite period reaches getNTimers(), whose static_cast of 1 + log(maxPeriod/...)/log2 is an undefined float->unsigned conversion: inf aborts the client in malloc via a garbage nTimers allocation, and NaN drives the search-timer wheel off a NaN period where every deadline comparison is false. Gate the parsed value on finite() (from epicsMath.h) and positivity alongside the parse status, and fall back to the default period. A non-positive period is not a "low" period to be clamped up to the 60 s lower limit; it takes the same invalid-input path as inf/NaN. getMaxPeriod() is getNTimers()'s only caller, so this makes the conversion finite and positive by construction. --- modules/ca/src/client/udpiiu.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/modules/ca/src/client/udpiiu.cpp b/modules/ca/src/client/udpiiu.cpp index e2c7a43f2..56f8592ba 100644 --- a/modules/ca/src/client/udpiiu.cpp +++ b/modules/ca/src/client/udpiiu.cpp @@ -30,6 +30,7 @@ #include "osiProcess.h" #include "osiWireFormat.h" #include "epicsAlgorithm.h" +#include "epicsMath.h" #include "errlog.h" #include "locationException.h" @@ -73,7 +74,7 @@ double getMaxPeriod() if ( envGetConfigParamPtr ( & EPICS_CA_MAX_SEARCH_PERIOD ) ) { long longStatus = envGetDoubleConfigParam ( & EPICS_CA_MAX_SEARCH_PERIOD, & maxPeriod ); - if ( ! longStatus ) { + if ( ! longStatus && finite ( maxPeriod ) && maxPeriod > 0.0 ) { if ( maxPeriod < maxSearchPeriodLowerLimit ) { epicsPrintf ( "\"%s\" out of range (low)\n", EPICS_CA_MAX_SEARCH_PERIOD.name ); @@ -83,7 +84,9 @@ double getMaxPeriod() } } else { - epicsPrintf ( "EPICS \"%s\" wasn't a real number\n", + /* Reset to default on parse error or out of range value */ + maxPeriod = maxSearchPeriodDefault; + epicsPrintf ( "EPICS \"%s\" was not a positive real number\n", EPICS_CA_MAX_SEARCH_PERIOD.name ); epicsPrintf ( "Setting \"%s\" = %f seconds\n", EPICS_CA_MAX_SEARCH_PERIOD.name, maxPeriod );