public inbox for ltp@lists.linux.it
 help / color / mirror / Atom feed
* [LTP] [PATCH v1] ioctl_pidfd02.c: fix clone3 EFAULT in 32-bit compat mode due to sign extension
@ 2026-01-25  6:30 Wei Gao via ltp
  2026-02-11 15:29 ` Andrea Cervesato via ltp
  2026-02-13  2:36 ` [LTP] [PATCH v2] " Wei Gao via ltp
  0 siblings, 2 replies; 7+ messages in thread
From: Wei Gao via ltp @ 2026-01-25  6:30 UTC (permalink / raw)
  To: ltp

When running 32-bit binaries on a 64-bit kernel (compat mode), the user
stack is often mapped in the upper range of the 32-bit address space
(e.g., 0xffxxxxxx).

Directly casting a 32-bit pointer to uint64_t for the args->pidfd field
in struct clone_args can trigger sign extension if the pointer's MSB
(Most Significant Bit) is 1. For example, a 32-bit user address
0xff80e0bc is incorrectly sign-extended to 0xfffffffffff80e0bc.

When the 64-bit kernel executes put_user(), it identifies this address
as being in the 64-bit kernel canonical range rather than user space,
leading to a failed access_ok() check and returning -EFAULT.

This patch fixes the issue by double-casting through uintptr_t to
ensure zero-extension, keeping the address within the valid 32-bit
user-space range from the kernel's perspective.

Signed-off-by: Wei Gao <wegao@suse.com>
---
 testcases/kernel/syscalls/ioctl/ioctl_pidfd02.c | 2 +-
 testcases/kernel/syscalls/ioctl/ioctl_pidfd03.c | 2 +-
 testcases/kernel/syscalls/ioctl/ioctl_pidfd04.c | 2 +-
 testcases/kernel/syscalls/ioctl/ioctl_pidfd05.c | 2 +-
 testcases/kernel/syscalls/ioctl/ioctl_pidfd06.c | 2 +-
 5 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/testcases/kernel/syscalls/ioctl/ioctl_pidfd02.c b/testcases/kernel/syscalls/ioctl/ioctl_pidfd02.c
index c6f8a02fe..cc44a1bb5 100644
--- a/testcases/kernel/syscalls/ioctl/ioctl_pidfd02.c
+++ b/testcases/kernel/syscalls/ioctl/ioctl_pidfd02.c
@@ -27,7 +27,7 @@ static void run(unsigned int isolate)
 
 	if (isolate) {
 		args->flags = CLONE_PIDFD | CLONE_NEWUSER | CLONE_NEWPID;
-		args->pidfd = (uint64_t)&pidfd;
+		args->pidfd = (uint64_t)(uintptr_t)&pidfd;
 		args->exit_signal = SIGCHLD;
 
 		pid_child = SAFE_CLONE(args);
diff --git a/testcases/kernel/syscalls/ioctl/ioctl_pidfd03.c b/testcases/kernel/syscalls/ioctl/ioctl_pidfd03.c
index 2c785004c..53223c0a5 100644
--- a/testcases/kernel/syscalls/ioctl/ioctl_pidfd03.c
+++ b/testcases/kernel/syscalls/ioctl/ioctl_pidfd03.c
@@ -24,7 +24,7 @@ static void run(void)
 	memset(args, 0, sizeof(struct tst_clone_args));
 
 	args->flags = CLONE_PIDFD | CLONE_NEWUSER | CLONE_NEWPID;
-	args->pidfd = (uint64_t)&pidfd;
+	args->pidfd = (uint64_t)(uintptr_t)&pidfd;
 	args->exit_signal = SIGCHLD;
 
 	pid_child = SAFE_CLONE(args);
diff --git a/testcases/kernel/syscalls/ioctl/ioctl_pidfd04.c b/testcases/kernel/syscalls/ioctl/ioctl_pidfd04.c
index ff4316068..0b0e4053c 100644
--- a/testcases/kernel/syscalls/ioctl/ioctl_pidfd04.c
+++ b/testcases/kernel/syscalls/ioctl/ioctl_pidfd04.c
@@ -26,7 +26,7 @@ static void run(void)
 	info->mask = PIDFD_INFO_EXIT;
 
 	args->flags = CLONE_PIDFD | CLONE_NEWUSER | CLONE_NEWPID;
-	args->pidfd = (uint64_t)&pidfd;
+	args->pidfd = (uint64_t)(uintptr_t)&pidfd;
 	args->exit_signal = SIGCHLD;
 
 	pid_child = SAFE_CLONE(args);
diff --git a/testcases/kernel/syscalls/ioctl/ioctl_pidfd05.c b/testcases/kernel/syscalls/ioctl/ioctl_pidfd05.c
index 278e64cef..a921b6b05 100644
--- a/testcases/kernel/syscalls/ioctl/ioctl_pidfd05.c
+++ b/testcases/kernel/syscalls/ioctl/ioctl_pidfd05.c
@@ -36,7 +36,7 @@ static void run(void)
 	info_invalid->dummy = 1;
 
 	args->flags = CLONE_PIDFD | CLONE_NEWUSER | CLONE_NEWPID;
-	args->pidfd = (uint64_t)&pidfd;
+	args->pidfd = (uint64_t)(uintptr_t)&pidfd;
 	args->exit_signal = SIGCHLD;
 
 	pid_child = SAFE_CLONE(args);
diff --git a/testcases/kernel/syscalls/ioctl/ioctl_pidfd06.c b/testcases/kernel/syscalls/ioctl/ioctl_pidfd06.c
index 95c09dbda..9e78ece82 100644
--- a/testcases/kernel/syscalls/ioctl/ioctl_pidfd06.c
+++ b/testcases/kernel/syscalls/ioctl/ioctl_pidfd06.c
@@ -26,7 +26,7 @@ static void run(void)
 	info->mask = PIDFD_INFO_EXIT;
 
 	args->flags = CLONE_PIDFD | CLONE_NEWUSER | CLONE_NEWPID;
-	args->pidfd = (uint64_t)&pidfd;
+	args->pidfd = (uint64_t)(uintptr_t)&pidfd;
 	args->exit_signal = SIGCHLD;
 
 	pid_child = SAFE_CLONE(args);
-- 
2.52.0


-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

^ permalink raw reply related	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2026-02-17 13:15 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-01-25  6:30 [LTP] [PATCH v1] ioctl_pidfd02.c: fix clone3 EFAULT in 32-bit compat mode due to sign extension Wei Gao via ltp
2026-02-11 15:29 ` Andrea Cervesato via ltp
2026-02-13  2:36 ` [LTP] [PATCH v2] " Wei Gao via ltp
2026-02-13  9:27   ` Cyril Hrubis
2026-02-13 10:25     ` Andrea Cervesato via ltp
2026-02-13 10:03   ` [LTP] [PATCH v3] " Wei Gao via ltp
2026-02-17 13:14     ` Andrea Cervesato via ltp

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox