[LTP] [PATCH] syscalls/stime: Fix Time Overflow for 2038 Problem on 32-bit Systems

jiaying.song.cn@windriver.com jiaying.song.cn@windriver.com
Mon Apr 28 09:38:11 CEST 2025


From: Jiaying Song <jiaying.song.cn@windriver.com>

This patch adapts time handling for the 2038 problem on 32-bit systems
by correcting output formatting, replacing __kernel_old_timeval with
timeval, and using settimeofday().

This modification includes the following:
1) Output type modification: On 32-bit systems, pres_time_tv.tv_sec may be long long (lld), and using %ld can cause overflow. The %lld specifier is used to correctly output long long values.
2) Change __kernel_old_timeval to timeval: On 32-bit architectures, __kernel_old_timeval's tv_sec is long, which overflows after 2038. Replacing it with timeval, which uses long long or int64_t, avoids this overflow issue.
3) Change tst_syscall(__NR_settimeofday) to settimeofday: Using tst_syscall for setting time beyond 2038 causes EINVAL errors due to incompatible types. Using settimeofday() (libc interface) solves this compatibility issue.

Error log:
stime01.c:36: TFAIL: stime(-2208988922) failed: EINVAL (22)

Signed-off-by: Jiaying Song <jiaying.song.cn@windriver.com>
---
 testcases/kernel/syscalls/stime/stime01.c   | 10 +++++-----
 testcases/kernel/syscalls/stime/stime_var.h |  4 ++--
 2 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/testcases/kernel/syscalls/stime/stime01.c b/testcases/kernel/syscalls/stime/stime01.c
index 82a340258..9e909d7ca 100644
--- a/testcases/kernel/syscalls/stime/stime01.c
+++ b/testcases/kernel/syscalls/stime/stime01.c
@@ -33,7 +33,7 @@ static void run(void)
 	new_time = real_time_tv.tv_sec + 30;
 
 	if (do_stime(&new_time) < 0) {
-		tst_res(TFAIL | TERRNO, "stime(%ld) failed", new_time);
+		tst_res(TFAIL | TERRNO, "stime(%jd) failed", (intmax_t)new_time);
 		return;
 	}
 
@@ -43,12 +43,12 @@ static void run(void)
 	switch (pres_time_tv.tv_sec - new_time) {
 	case 0:
 	case 1:
-		tst_res(TINFO, "pt.tv_sec: %ld", pres_time_tv.tv_sec);
-		tst_res(TPASS, "system time was set to %ld", new_time);
+		tst_res(TINFO, "pt.tv_sec: %jd", (intmax_t)pres_time_tv.tv_sec);
+		tst_res(TPASS, "system time was set to %jd", (intmax_t)new_time);
 	break;
 	default:
-		tst_res(TFAIL, "system time not set to %ld (got: %ld)",
-			new_time, pres_time_tv.tv_sec);
+		tst_res(TFAIL, "system time not set to %jd (got: %jd)",
+			(intmax_t)new_time, (intmax_t)pres_time_tv.tv_sec);
 	}
 }
 
diff --git a/testcases/kernel/syscalls/stime/stime_var.h b/testcases/kernel/syscalls/stime/stime_var.h
index 708b80573..326240972 100644
--- a/testcases/kernel/syscalls/stime/stime_var.h
+++ b/testcases/kernel/syscalls/stime/stime_var.h
@@ -27,12 +27,12 @@ static int do_stime(time_t *ntime)
 	case 1:
 		return tst_syscall(__NR_stime, ntime);
 	case 2: {
-		struct __kernel_old_timeval tv;
+		struct timeval tv;
 
 		tv.tv_sec = *ntime;
 		tv.tv_usec = 0;
 
-		return tst_syscall(__NR_settimeofday, &tv, (struct timezone *) 0);
+		return settimeofday(&tv, (struct timezone *) 0);
 	}
 	}
 
-- 
2.34.1



More information about the ltp mailing list