All of lore.kernel.org
 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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.