From 7f99a15ccf30eb07facfe38cb1c3cfd85178a84f Mon Sep 17 00:00:00 2001 From: dongjiuzhu1 Date: Wed, 3 Jan 2024 11:24:25 +0800 Subject: [PATCH] libc/time: add g_lcl_lock to protect local context in localsub 0x0c1561f8 in localsub (tmp=0x3c887088, offset=0, timep=0x3c887078) at time/lib_localtime.c:1993 localtime_r (timep=0x3c887078, timep@entry=0x3c887088, tmp=0x3c887088, tmp@entry=0x3c887098) at time/lib_localtime.c:2819 0x0c1225c8 in nx_vsyslog (priority=7, fmt=0x2c6d9700 , ap=0x3c887170, ap@entry=0x3c887178) at syslog/vsyslog.c:135 0x0c152068 in vsyslog (priority=priority@entry=7, fmt=fmt@entry=0x2c6d9700 , ap=ap@entry=...) at syslog/lib_syslog.c:68 0x0c152098 in syslog (priority=priority@entry=7, fmt=0x2c6d9700 ) at syslog/lib_syslog.c:100 Signed-off-by: dongjiuzhu1 --- libs/libc/time/lib_localtime.c | 51 ++++++++++++++++++++++------------ 1 file changed, 33 insertions(+), 18 deletions(-) diff --git a/libs/libc/time/lib_localtime.c b/libs/libc/time/lib_localtime.c index 60bb59f4d2..6398b2529c 100644 --- a/libs/libc/time/lib_localtime.c +++ b/libs/libc/time/lib_localtime.c @@ -396,6 +396,30 @@ static int tzparse(FAR const char *name, FAR struct state_s *sp, * Private Functions ****************************************************************************/ +static inline void tz_lock(FAR rmutex_t *lock) +{ +#ifndef __KERNEL__ + if (up_interrupt_context() || (sched_idletask() && OSINIT_IDLELOOP())) + { + return; + } +#endif + + nxrmutex_lock(lock); +} + +static inline void tz_unlock(FAR rmutex_t *lock) +{ +#ifndef __KERNEL__ + if (up_interrupt_context() || (sched_idletask() && OSINIT_IDLELOOP())) + { + return; + } +#endif + + nxrmutex_unlock(lock); +} + /* Initialize *S to a value based on UTOFF, ISDST, and DESIGIDX. */ static void init_ttinfo(FAR struct ttinfo_s *s, int_fast32_t utoff, @@ -1912,6 +1936,7 @@ static FAR struct tm *localsub(FAR const time_t *timep, return NULL; } + tz_lock(&g_lcl_lock); if ((sp->goback && t < sp->ats[0]) || (sp->goahead && t > sp->ats[sp->timecnt - 1])) { @@ -1948,6 +1973,7 @@ static FAR struct tm *localsub(FAR const time_t *timep, if (newt < sp->ats[0] || newt > sp->ats[sp->timecnt - 1]) { + tz_unlock(&g_lcl_lock); return NULL; /* "cannot happen" */ } @@ -1968,12 +1994,14 @@ static FAR struct tm *localsub(FAR const time_t *timep, if (newy < INT_MIN || newy > INT_MAX) { + tz_unlock(&g_lcl_lock); return NULL; } result->tm_year = newy; } + tz_unlock(&g_lcl_lock); return result; } @@ -2019,6 +2047,7 @@ static FAR struct tm *localsub(FAR const time_t *timep, result->tm_zone = tzname[result->tm_isdst]; } + tz_unlock(&g_lcl_lock); return result; } @@ -2029,14 +2058,7 @@ static FAR struct tm *gmtsub(FAR const time_t *timep, { if (!g_gmt_isset) { -#ifndef __KERNEL__ - if (up_interrupt_context() || (sched_idletask() && OSINIT_IDLELOOP())) - { - return NULL; - } -#endif - - nxrmutex_lock(&g_gmt_lock); + tz_lock(&g_gmt_lock); if (!g_gmt_isset) { @@ -2048,7 +2070,7 @@ static FAR struct tm *gmtsub(FAR const time_t *timep, } } - nxrmutex_unlock(&g_gmt_lock); + tz_unlock(&g_gmt_lock); } tmp->tm_zone = ((FAR char *)(offset ? g_wildabbr : @@ -2758,13 +2780,6 @@ void tzset(void) { FAR const char *name; -#ifndef __KERNEL__ - if (up_interrupt_context() || (sched_idletask() && OSINIT_IDLELOOP())) - { - return; - } -#endif - name = getenv("TZ"); if (name == NULL) { @@ -2781,7 +2796,7 @@ void tzset(void) return; } - nxrmutex_lock(&g_lcl_lock); + tz_lock(&g_lcl_lock); if (g_lcl_ptr == NULL) { @@ -2802,7 +2817,7 @@ void tzset(void) tzname: settzname(); g_lcl_isset = 1; - nxrmutex_unlock(&g_lcl_lock); + tz_unlock(&g_lcl_lock); } FAR struct tm *localtime(FAR const time_t *timep)