diff mbox series

syscalls/stime: Fix Time Overflow for 2038 Problem on 32-bit Systems

Message ID 20250428073811.133441-1-jiaying.song.cn@windriver.com
State Needs Review / ACK
Headers show
Series syscalls/stime: Fix Time Overflow for 2038 Problem on 32-bit Systems | expand

Checks

Context Check Description
ltpci/debian_stable_s390x-linux-gnu-gcc_s390x success success
ltpci/debian_stable_powerpc64le-linux-gnu-gcc_ppc64el success success
ltpci/debian_stable_aarch64-linux-gnu-gcc_arm64 success success
ltpci/debian_stable_gcc success success
ltpci/debian_stable_gcc success success
ltpci/ubuntu_jammy_gcc success success
ltpci/alpine_latest_gcc success success
ltpci/ubuntu_bionic_gcc success success
ltpci/opensuse-leap_latest_gcc success success
ltpci/debian_testing_gcc success success
ltpci/quay-io-centos-centos_stream9_gcc success success
ltpci/debian_oldstable_gcc success success
ltpci/debian_oldstable_clang success success
ltpci/fedora_latest_clang success success
ltpci/debian_testing_clang success success
ltpci/opensuse-archive_42-2_gcc success success

Commit Message

Song, Jiaying \(CN\) via ltp April 28, 2025, 7:38 a.m. UTC
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(-)

Comments

Andrea Cervesato April 30, 2025, 7:29 a.m. UTC | #1
Hi!

I noticed that stime01 is equivalent to settimeofday01 when 
tst_variant=2. So I'm wondering if it makes sense to keep that variant, 
considering that it creates issues in 32bit systems. In my opinion, we 
should probably remove the usage of settimeofday inside stime01 and to 
keep settimeofday01 instead.

@Petr @Cyril WDYT?

Kind regards,
Andrea Cervesato
Song, Jiaying \(CN\) via ltp May 7, 2025, 7:55 a.m. UTC | #2
Dear Andrea Cervesato,

If the goal of stime01 (with tst_variant=2) is specifically to test the settimeofday syscall directly, then my patch is not appropriate.

After further investigation, I found that the failure on 32-bit Y2038 systems is mainly due to the fact that the kernel's syscall implementation:

SYSCALL_DEFINE2(settimeofday, struct __kernel_old_timeval __user *, tv,
                struct timezone __user *, tz)

does not support Y2038, since it relies on __kernel_old_timeval.

So the test case fails for expected reasons. Please feel free to disregard my patch.

Kind regards,
Jiaying.

-----Original Message-----
From: Andrea Cervesato <andrea.cervesato@suse.com> 
Sent: Wednesday, April 30, 2025 3:29 PM
To: Song, Jiaying (CN) <Jiaying.Song.CN@windriver.com>; ltp@lists.linux.it
Cc: Cyril Hrubis <chrubis@suse.cz>; Petr Vorel <pvorel@suse.cz>
Subject: Re: [LTP] [PATCH] syscalls/stime: Fix Time Overflow for 2038 Problem on 32-bit Systems

CAUTION: This email comes from a non Wind River email account!
Do not click links or open attachments unless you recognize the sender and know the content is safe.

Hi!

I noticed that stime01 is equivalent to settimeofday01 when tst_variant=2. So I'm wondering if it makes sense to keep that variant, considering that it creates issues in 32bit systems. In my opinion, we should probably remove the usage of settimeofday inside stime01 and to keep settimeofday01 instead.

@Petr @Cyril WDYT?

Kind regards,
Andrea Cervesato
Petr Vorel May 7, 2025, 1:43 p.m. UTC | #3
Hi Andrea,

> Hi!

> I noticed that stime01 is equivalent to settimeofday01 when tst_variant=2.
> So I'm wondering if it makes sense to keep that variant, considering that it
> creates issues in 32bit systems. In my opinion, we should probably remove
> the usage of settimeofday inside stime01 and to keep settimeofday01 instead.

> @Petr @Cyril WDYT?

IMHO it's not the same. settimeofday01.c calls settimeofday() libc wrapper,
but stime01.c in tst_variant=2 calls __NR_settimeofday raw syscall.

Kind regards,
Petr

> Kind regards,
> Andrea Cervesato
diff mbox series

Patch

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);
 	}
 	}