]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
arch: copy_thread: pass clone_flags as u64
authorSimon Schuster <schuster.simon@siemens-energy.com>
Mon, 1 Sep 2025 13:09:52 +0000 (15:09 +0200)
committerChristian Brauner <brauner@kernel.org>
Mon, 1 Sep 2025 13:31:34 +0000 (15:31 +0200)
With the introduction of clone3 in commit 7f192e3cd316 ("fork: add
clone3") the effective bit width of clone_flags on all architectures was
increased from 32-bit to 64-bit, with a new type of u64 for the flags.
However, for most consumers of clone_flags the interface was not
changed from the previous type of unsigned long.

While this works fine as long as none of the new 64-bit flag bits
(CLONE_CLEAR_SIGHAND and CLONE_INTO_CGROUP) are evaluated, this is still
undesirable in terms of the principle of least surprise.

Thus, this commit fixes all relevant interfaces of the copy_thread
function that is called from copy_process to consistently pass
clone_flags as u64, so that no truncation to 32-bit integers occurs on
32-bit architectures.

Signed-off-by: Simon Schuster <schuster.simon@siemens-energy.com>
Link: https://lore.kernel.org/20250901-nios2-implement-clone3-v2-3-53fcf5577d57@siemens-energy.com
Fixes: c5febea0956fd387 ("fork: Pass struct kernel_clone_args into copy_thread")
Acked-by: Guo Ren (Alibaba Damo Academy) <guoren@kernel.org>
Acked-by: Andreas Larsson <andreas@gaisler.com> # sparc
Acked-by: David Hildenbrand <david@redhat.com>
Acked-by: Geert Uytterhoeven <geert@linux-m68k.org> # m68k
Reviewed-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Christian Brauner <brauner@kernel.org>
26 files changed:
arch/alpha/kernel/process.c
arch/arc/kernel/process.c
arch/arm/kernel/process.c
arch/arm64/kernel/process.c
arch/csky/kernel/process.c
arch/hexagon/kernel/process.c
arch/loongarch/kernel/process.c
arch/m68k/kernel/process.c
arch/microblaze/kernel/process.c
arch/mips/kernel/process.c
arch/nios2/kernel/process.c
arch/openrisc/kernel/process.c
arch/parisc/kernel/process.c
arch/powerpc/kernel/process.c
arch/riscv/kernel/process.c
arch/s390/kernel/process.c
arch/sh/kernel/process_32.c
arch/sparc/kernel/process_32.c
arch/sparc/kernel/process_64.c
arch/um/kernel/process.c
arch/x86/include/asm/fpu/sched.h
arch/x86/include/asm/shstk.h
arch/x86/kernel/fpu/core.c
arch/x86/kernel/process.c
arch/x86/kernel/shstk.c
arch/xtensa/kernel/process.c

index 582d96548385dd63e392ed27a25dde367f0b4d3a..06522451f018f3990f7e2505c4153a007298b338 100644 (file)
@@ -231,7 +231,7 @@ flush_thread(void)
  */
 int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
 {
-       unsigned long clone_flags = args->flags;
+       u64 clone_flags = args->flags;
        unsigned long usp = args->stack;
        unsigned long tls = args->tls;
        extern void ret_from_fork(void);
index 186ceab661eb02e611ffafba8e746a07bddf4437..8166d090871304605ac6b8a9fb6c24c83aa131b9 100644 (file)
@@ -166,7 +166,7 @@ asmlinkage void ret_from_fork(void);
  */
 int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
 {
-       unsigned long clone_flags = args->flags;
+       u64 clone_flags = args->flags;
        unsigned long usp = args->stack;
        unsigned long tls = args->tls;
        struct pt_regs *c_regs;        /* child's pt_regs */
index e16ed102960cb01d625e2ccc484f238b824b03b3..d7aa95225c70bd93d990656d56553113917f6f56 100644 (file)
@@ -234,7 +234,7 @@ asmlinkage void ret_from_fork(void) __asm__("ret_from_fork");
 
 int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
 {
-       unsigned long clone_flags = args->flags;
+       u64 clone_flags = args->flags;
        unsigned long stack_start = args->stack;
        unsigned long tls = args->tls;
        struct thread_info *thread = task_thread_info(p);
index 96482a1412c6aa927fd366548abe2eb653ee0fd0..fba7ca102a8c42feb0c5920238cadf1881971cea 100644 (file)
@@ -409,7 +409,7 @@ asmlinkage void ret_from_fork(void) asm("ret_from_fork");
 
 int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
 {
-       unsigned long clone_flags = args->flags;
+       u64 clone_flags = args->flags;
        unsigned long stack_start = args->stack;
        unsigned long tls = args->tls;
        struct pt_regs *childregs = task_pt_regs(p);
index 0c6e4b17fe00fd519f4f1e2d4cf446a55f4320fb..a7a90340042a5fec5609ca986cff76489c199cb4 100644 (file)
@@ -32,7 +32,7 @@ void flush_thread(void){}
 
 int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
 {
-       unsigned long clone_flags = args->flags;
+       u64 clone_flags = args->flags;
        unsigned long usp = args->stack;
        unsigned long tls = args->tls;
        struct switch_stack *childstack;
index 2a77bfd7569450ce4cf30af9376819628feeb559..15b4992bfa298a022ad1d3afbf44502056dc03d3 100644 (file)
@@ -52,7 +52,7 @@ void arch_cpu_idle(void)
  */
 int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
 {
-       unsigned long clone_flags = args->flags;
+       u64 clone_flags = args->flags;
        unsigned long usp = args->stack;
        unsigned long tls = args->tls;
        struct thread_info *ti = task_thread_info(p);
index 3582f591bab286c30127e715c47d485f74d5e2ca..efd9edf65603ccd16408dbe5d2b71a47d08561ff 100644 (file)
@@ -167,7 +167,7 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
        unsigned long childksp;
        unsigned long tls = args->tls;
        unsigned long usp = args->stack;
-       unsigned long clone_flags = args->flags;
+       u64 clone_flags = args->flags;
        struct pt_regs *childregs, *regs = current_pt_regs();
 
        childksp = (unsigned long)task_stack_page(p) + THREAD_SIZE;
index fda7eac23f872d06747ec8d13b44a6fd33d66a54..f5a07a70e9385ab1c9f7e1df7f65c1a04d9e8199 100644 (file)
@@ -141,7 +141,7 @@ asmlinkage int m68k_clone3(struct pt_regs *regs)
 
 int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
 {
-       unsigned long clone_flags = args->flags;
+       u64 clone_flags = args->flags;
        unsigned long usp = args->stack;
        unsigned long tls = args->tls;
        struct fork_frame {
index 56342e11442d2a8f86844ae5f6025a5728a6f239..6cbf642d7b801d4acb9243ad4bbe79cd397384cf 100644 (file)
@@ -54,7 +54,7 @@ void flush_thread(void)
 
 int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
 {
-       unsigned long clone_flags = args->flags;
+       u64 clone_flags = args->flags;
        unsigned long usp = args->stack;
        unsigned long tls = args->tls;
        struct pt_regs *childregs = task_pt_regs(p);
index 02aa6a04a21da437909eeac4f149155cc298f5b5..29191fa1801e2a5d9bcf9e7771d279d2e96e6344 100644 (file)
@@ -107,7 +107,7 @@ int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src)
  */
 int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
 {
-       unsigned long clone_flags = args->flags;
+       u64 clone_flags = args->flags;
        unsigned long usp = args->stack;
        unsigned long tls = args->tls;
        struct thread_info *ti = task_thread_info(p);
index f84021303f6a82ce3fc8635ef680cf422b9b4db9..151404139085cf77481109e279e7eee06c74727d 100644 (file)
@@ -101,7 +101,7 @@ void flush_thread(void)
 
 int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
 {
-       unsigned long clone_flags = args->flags;
+       u64 clone_flags = args->flags;
        unsigned long usp = args->stack;
        unsigned long tls = args->tls;
        struct pt_regs *childregs = task_pt_regs(p);
index eef99fee2110cb26fcd95fadcd44254208039600..73ffb9fa3118bb9582255f251a12c62454c4ec59 100644 (file)
@@ -165,7 +165,7 @@ extern asmlinkage void ret_from_fork(void);
 int
 copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
 {
-       unsigned long clone_flags = args->flags;
+       u64 clone_flags = args->flags;
        unsigned long usp = args->stack;
        unsigned long tls = args->tls;
        struct pt_regs *userregs;
index ed93bd8c154533a066acb700138ace6ef5342ee7..e64ab5d2a40d618683d3dbc00b2387062076442a 100644 (file)
@@ -201,7 +201,7 @@ arch_initcall(parisc_idle_init);
 int
 copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
 {
-       unsigned long clone_flags = args->flags;
+       u64 clone_flags = args->flags;
        unsigned long usp = args->stack;
        unsigned long tls = args->tls;
        struct pt_regs *cregs = &(p->thread.regs);
index 855e0988650326c5f3e43ec1202b28294df8b026..eb23966ac0a9f05175ae06274b2eb57d9efc7d5a 100644 (file)
@@ -1805,7 +1805,7 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
                        f = ret_from_kernel_user_thread;
                } else {
                        struct pt_regs *regs = current_pt_regs();
-                       unsigned long clone_flags = args->flags;
+                       u64 clone_flags = args->flags;
                        unsigned long usp = args->stack;
 
                        /* Copy registers */
index a0a40889d79a53a0b090567581761002f1facccb..31a392993cb4521e035065a0e51c12a6c4b36f6f 100644 (file)
@@ -223,7 +223,7 @@ asmlinkage void ret_from_fork_user(struct pt_regs *regs)
 
 int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
 {
-       unsigned long clone_flags = args->flags;
+       u64 clone_flags = args->flags;
        unsigned long usp = args->stack;
        unsigned long tls = args->tls;
        struct pt_regs *childregs = task_pt_regs(p);
index f55f09cda6f889c1dad3fafce8a79d343ee6c085..b107dbca4ed7df55f5f12fdbf00b6d5a7c0fdfa3 100644 (file)
@@ -106,7 +106,7 @@ int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src)
 
 int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
 {
-       unsigned long clone_flags = args->flags;
+       u64 clone_flags = args->flags;
        unsigned long new_stackp = args->stack;
        unsigned long tls = args->tls;
        struct fake_frame
index 92b6649d492952ce6943ed2c535337cfd27508ca..62f753a85b89c70e5331a7c779fbeed08d70fa8c 100644 (file)
@@ -89,7 +89,7 @@ asmlinkage void ret_from_kernel_thread(void);
 
 int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
 {
-       unsigned long clone_flags = args->flags;
+       u64 clone_flags = args->flags;
        unsigned long usp = args->stack;
        unsigned long tls = args->tls;
        struct thread_info *ti = task_thread_info(p);
index 9c7c662cb5659e0e766f3884bcf06b016f2c922f..5a28c0e91bf15f32161423a4cfe1b4f4c19688d9 100644 (file)
@@ -260,7 +260,7 @@ extern void ret_from_kernel_thread(void);
 
 int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
 {
-       unsigned long clone_flags = args->flags;
+       u64 clone_flags = args->flags;
        unsigned long sp = args->stack;
        unsigned long tls = args->tls;
        struct thread_info *ti = task_thread_info(p);
index 529adfecd58ca1ee98199c64e30ea00e232b439f..25781923788a03e1fad80b5674fa6e1ff86fefe8 100644 (file)
@@ -567,7 +567,7 @@ barf:
  */
 int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
 {
-       unsigned long clone_flags = args->flags;
+       u64 clone_flags = args->flags;
        unsigned long sp = args->stack;
        unsigned long tls = args->tls;
        struct thread_info *t = task_thread_info(p);
index 1be644de9e41ecdb94d379760ee8790c1d0657c6..9c9c66dc45f054375b1c3851d8ea833f7650e7eb 100644 (file)
@@ -143,7 +143,7 @@ static void fork_handler(void)
 
 int copy_thread(struct task_struct * p, const struct kernel_clone_args *args)
 {
-       unsigned long clone_flags = args->flags;
+       u64 clone_flags = args->flags;
        unsigned long sp = args->stack;
        unsigned long tls = args->tls;
        void (*handler)(void);
index c060549c6c94071f1962d124d93a318710f3d2f5..89004f4ca208dae2bd787828db95a4c1bc457315 100644 (file)
@@ -11,7 +11,7 @@
 
 extern void save_fpregs_to_fpstate(struct fpu *fpu);
 extern void fpu__drop(struct task_struct *tsk);
-extern int  fpu_clone(struct task_struct *dst, unsigned long clone_flags, bool minimal,
+extern int  fpu_clone(struct task_struct *dst, u64 clone_flags, bool minimal,
                      unsigned long shstk_addr);
 extern void fpu_flush_thread(void);
 
index ba6f2fe438488d7df08b0d415649652bc51cbe5c..0f50e01259430c0a4e49c53ee3151117e8ab5004 100644 (file)
@@ -16,7 +16,7 @@ struct thread_shstk {
 
 long shstk_prctl(struct task_struct *task, int option, unsigned long arg2);
 void reset_thread_features(void);
-unsigned long shstk_alloc_thread_stack(struct task_struct *p, unsigned long clone_flags,
+unsigned long shstk_alloc_thread_stack(struct task_struct *p, u64 clone_flags,
                                       unsigned long stack_size);
 void shstk_free(struct task_struct *p);
 int setup_signal_shadow_stack(struct ksignal *ksig);
@@ -28,7 +28,7 @@ static inline long shstk_prctl(struct task_struct *task, int option,
                               unsigned long arg2) { return -EINVAL; }
 static inline void reset_thread_features(void) {}
 static inline unsigned long shstk_alloc_thread_stack(struct task_struct *p,
-                                                    unsigned long clone_flags,
+                                                    u64 clone_flags,
                                                     unsigned long stack_size) { return 0; }
 static inline void shstk_free(struct task_struct *p) {}
 static inline int setup_signal_shadow_stack(struct ksignal *ksig) { return 0; }
index aefd412a23dc24d3f17916917880ea56974d4586..1f71cc135e9ade0ab5b30ed3c0348fb4f349cb71 100644 (file)
@@ -631,7 +631,7 @@ static int update_fpu_shstk(struct task_struct *dst, unsigned long ssp)
 }
 
 /* Clone current's FPU state on fork */
-int fpu_clone(struct task_struct *dst, unsigned long clone_flags, bool minimal,
+int fpu_clone(struct task_struct *dst, u64 clone_flags, bool minimal,
              unsigned long ssp)
 {
        /*
index 1b7960cf6eb0c177b1114734d0c56feac9913f95..e3a3987b0c4fb6cf9b08e806b4034cf6f638879d 100644 (file)
@@ -159,7 +159,7 @@ __visible void ret_from_fork(struct task_struct *prev, struct pt_regs *regs,
 
 int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
 {
-       unsigned long clone_flags = args->flags;
+       u64 clone_flags = args->flags;
        unsigned long sp = args->stack;
        unsigned long tls = args->tls;
        struct inactive_task_frame *frame;
index 2ddf23387c7ef75c30c32ff06bddb21fd33d670c..5eba6c5a67757df6aba3c7507142d5a16629aeda 100644 (file)
@@ -191,7 +191,7 @@ void reset_thread_features(void)
        current->thread.features_locked = 0;
 }
 
-unsigned long shstk_alloc_thread_stack(struct task_struct *tsk, unsigned long clone_flags,
+unsigned long shstk_alloc_thread_stack(struct task_struct *tsk, u64 clone_flags,
                                       unsigned long stack_size)
 {
        struct thread_shstk *shstk = &tsk->thread.shstk;
index 7bd66677f7b6de58d0a1bda1b414ebc622dce962..94d43f44be13158055a8133e1f5c7fe5b1b64939 100644 (file)
@@ -267,7 +267,7 @@ int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src)
 
 int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
 {
-       unsigned long clone_flags = args->flags;
+       u64 clone_flags = args->flags;
        unsigned long usp_thread_fn = args->stack;
        unsigned long tls = args->tls;
        struct pt_regs *childregs = task_pt_regs(p);