Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

arch: copy_thread: pass clone_flags as u64

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>

authored by

Simon Schuster and committed by
Christian Brauner
bbc46b23 edd3cb05

+27 -27
+1 -1
arch/alpha/kernel/process.c
··· 231 231 */ 232 232 int copy_thread(struct task_struct *p, const struct kernel_clone_args *args) 233 233 { 234 - unsigned long clone_flags = args->flags; 234 + u64 clone_flags = args->flags; 235 235 unsigned long usp = args->stack; 236 236 unsigned long tls = args->tls; 237 237 extern void ret_from_fork(void);
+1 -1
arch/arc/kernel/process.c
··· 166 166 */ 167 167 int copy_thread(struct task_struct *p, const struct kernel_clone_args *args) 168 168 { 169 - unsigned long clone_flags = args->flags; 169 + u64 clone_flags = args->flags; 170 170 unsigned long usp = args->stack; 171 171 unsigned long tls = args->tls; 172 172 struct pt_regs *c_regs; /* child's pt_regs */
+1 -1
arch/arm/kernel/process.c
··· 234 234 235 235 int copy_thread(struct task_struct *p, const struct kernel_clone_args *args) 236 236 { 237 - unsigned long clone_flags = args->flags; 237 + u64 clone_flags = args->flags; 238 238 unsigned long stack_start = args->stack; 239 239 unsigned long tls = args->tls; 240 240 struct thread_info *thread = task_thread_info(p);
+1 -1
arch/arm64/kernel/process.c
··· 409 409 410 410 int copy_thread(struct task_struct *p, const struct kernel_clone_args *args) 411 411 { 412 - unsigned long clone_flags = args->flags; 412 + u64 clone_flags = args->flags; 413 413 unsigned long stack_start = args->stack; 414 414 unsigned long tls = args->tls; 415 415 struct pt_regs *childregs = task_pt_regs(p);
+1 -1
arch/csky/kernel/process.c
··· 32 32 33 33 int copy_thread(struct task_struct *p, const struct kernel_clone_args *args) 34 34 { 35 - unsigned long clone_flags = args->flags; 35 + u64 clone_flags = args->flags; 36 36 unsigned long usp = args->stack; 37 37 unsigned long tls = args->tls; 38 38 struct switch_stack *childstack;
+1 -1
arch/hexagon/kernel/process.c
··· 52 52 */ 53 53 int copy_thread(struct task_struct *p, const struct kernel_clone_args *args) 54 54 { 55 - unsigned long clone_flags = args->flags; 55 + u64 clone_flags = args->flags; 56 56 unsigned long usp = args->stack; 57 57 unsigned long tls = args->tls; 58 58 struct thread_info *ti = task_thread_info(p);
+1 -1
arch/loongarch/kernel/process.c
··· 167 167 unsigned long childksp; 168 168 unsigned long tls = args->tls; 169 169 unsigned long usp = args->stack; 170 - unsigned long clone_flags = args->flags; 170 + u64 clone_flags = args->flags; 171 171 struct pt_regs *childregs, *regs = current_pt_regs(); 172 172 173 173 childksp = (unsigned long)task_stack_page(p) + THREAD_SIZE;
+1 -1
arch/m68k/kernel/process.c
··· 141 141 142 142 int copy_thread(struct task_struct *p, const struct kernel_clone_args *args) 143 143 { 144 - unsigned long clone_flags = args->flags; 144 + u64 clone_flags = args->flags; 145 145 unsigned long usp = args->stack; 146 146 unsigned long tls = args->tls; 147 147 struct fork_frame {
+1 -1
arch/microblaze/kernel/process.c
··· 54 54 55 55 int copy_thread(struct task_struct *p, const struct kernel_clone_args *args) 56 56 { 57 - unsigned long clone_flags = args->flags; 57 + u64 clone_flags = args->flags; 58 58 unsigned long usp = args->stack; 59 59 unsigned long tls = args->tls; 60 60 struct pt_regs *childregs = task_pt_regs(p);
+1 -1
arch/mips/kernel/process.c
··· 107 107 */ 108 108 int copy_thread(struct task_struct *p, const struct kernel_clone_args *args) 109 109 { 110 - unsigned long clone_flags = args->flags; 110 + u64 clone_flags = args->flags; 111 111 unsigned long usp = args->stack; 112 112 unsigned long tls = args->tls; 113 113 struct thread_info *ti = task_thread_info(p);
+1 -1
arch/nios2/kernel/process.c
··· 101 101 102 102 int copy_thread(struct task_struct *p, const struct kernel_clone_args *args) 103 103 { 104 - unsigned long clone_flags = args->flags; 104 + u64 clone_flags = args->flags; 105 105 unsigned long usp = args->stack; 106 106 unsigned long tls = args->tls; 107 107 struct pt_regs *childregs = task_pt_regs(p);
+1 -1
arch/openrisc/kernel/process.c
··· 165 165 int 166 166 copy_thread(struct task_struct *p, const struct kernel_clone_args *args) 167 167 { 168 - unsigned long clone_flags = args->flags; 168 + u64 clone_flags = args->flags; 169 169 unsigned long usp = args->stack; 170 170 unsigned long tls = args->tls; 171 171 struct pt_regs *userregs;
+1 -1
arch/parisc/kernel/process.c
··· 201 201 int 202 202 copy_thread(struct task_struct *p, const struct kernel_clone_args *args) 203 203 { 204 - unsigned long clone_flags = args->flags; 204 + u64 clone_flags = args->flags; 205 205 unsigned long usp = args->stack; 206 206 unsigned long tls = args->tls; 207 207 struct pt_regs *cregs = &(p->thread.regs);
+1 -1
arch/powerpc/kernel/process.c
··· 1805 1805 f = ret_from_kernel_user_thread; 1806 1806 } else { 1807 1807 struct pt_regs *regs = current_pt_regs(); 1808 - unsigned long clone_flags = args->flags; 1808 + u64 clone_flags = args->flags; 1809 1809 unsigned long usp = args->stack; 1810 1810 1811 1811 /* Copy registers */
+1 -1
arch/riscv/kernel/process.c
··· 223 223 224 224 int copy_thread(struct task_struct *p, const struct kernel_clone_args *args) 225 225 { 226 - unsigned long clone_flags = args->flags; 226 + u64 clone_flags = args->flags; 227 227 unsigned long usp = args->stack; 228 228 unsigned long tls = args->tls; 229 229 struct pt_regs *childregs = task_pt_regs(p);
+1 -1
arch/s390/kernel/process.c
··· 106 106 107 107 int copy_thread(struct task_struct *p, const struct kernel_clone_args *args) 108 108 { 109 - unsigned long clone_flags = args->flags; 109 + u64 clone_flags = args->flags; 110 110 unsigned long new_stackp = args->stack; 111 111 unsigned long tls = args->tls; 112 112 struct fake_frame
+1 -1
arch/sh/kernel/process_32.c
··· 89 89 90 90 int copy_thread(struct task_struct *p, const struct kernel_clone_args *args) 91 91 { 92 - unsigned long clone_flags = args->flags; 92 + u64 clone_flags = args->flags; 93 93 unsigned long usp = args->stack; 94 94 unsigned long tls = args->tls; 95 95 struct thread_info *ti = task_thread_info(p);
+1 -1
arch/sparc/kernel/process_32.c
··· 260 260 261 261 int copy_thread(struct task_struct *p, const struct kernel_clone_args *args) 262 262 { 263 - unsigned long clone_flags = args->flags; 263 + u64 clone_flags = args->flags; 264 264 unsigned long sp = args->stack; 265 265 unsigned long tls = args->tls; 266 266 struct thread_info *ti = task_thread_info(p);
+1 -1
arch/sparc/kernel/process_64.c
··· 567 567 */ 568 568 int copy_thread(struct task_struct *p, const struct kernel_clone_args *args) 569 569 { 570 - unsigned long clone_flags = args->flags; 570 + u64 clone_flags = args->flags; 571 571 unsigned long sp = args->stack; 572 572 unsigned long tls = args->tls; 573 573 struct thread_info *t = task_thread_info(p);
+1 -1
arch/um/kernel/process.c
··· 143 143 144 144 int copy_thread(struct task_struct * p, const struct kernel_clone_args *args) 145 145 { 146 - unsigned long clone_flags = args->flags; 146 + u64 clone_flags = args->flags; 147 147 unsigned long sp = args->stack; 148 148 unsigned long tls = args->tls; 149 149 void (*handler)(void);
+1 -1
arch/x86/include/asm/fpu/sched.h
··· 11 11 12 12 extern void save_fpregs_to_fpstate(struct fpu *fpu); 13 13 extern void fpu__drop(struct task_struct *tsk); 14 - extern int fpu_clone(struct task_struct *dst, unsigned long clone_flags, bool minimal, 14 + extern int fpu_clone(struct task_struct *dst, u64 clone_flags, bool minimal, 15 15 unsigned long shstk_addr); 16 16 extern void fpu_flush_thread(void); 17 17
+2 -2
arch/x86/include/asm/shstk.h
··· 16 16 17 17 long shstk_prctl(struct task_struct *task, int option, unsigned long arg2); 18 18 void reset_thread_features(void); 19 - unsigned long shstk_alloc_thread_stack(struct task_struct *p, unsigned long clone_flags, 19 + unsigned long shstk_alloc_thread_stack(struct task_struct *p, u64 clone_flags, 20 20 unsigned long stack_size); 21 21 void shstk_free(struct task_struct *p); 22 22 int setup_signal_shadow_stack(struct ksignal *ksig); ··· 28 28 unsigned long arg2) { return -EINVAL; } 29 29 static inline void reset_thread_features(void) {} 30 30 static inline unsigned long shstk_alloc_thread_stack(struct task_struct *p, 31 - unsigned long clone_flags, 31 + u64 clone_flags, 32 32 unsigned long stack_size) { return 0; } 33 33 static inline void shstk_free(struct task_struct *p) {} 34 34 static inline int setup_signal_shadow_stack(struct ksignal *ksig) { return 0; }
+1 -1
arch/x86/kernel/fpu/core.c
··· 631 631 } 632 632 633 633 /* Clone current's FPU state on fork */ 634 - int fpu_clone(struct task_struct *dst, unsigned long clone_flags, bool minimal, 634 + int fpu_clone(struct task_struct *dst, u64 clone_flags, bool minimal, 635 635 unsigned long ssp) 636 636 { 637 637 /*
+1 -1
arch/x86/kernel/process.c
··· 159 159 160 160 int copy_thread(struct task_struct *p, const struct kernel_clone_args *args) 161 161 { 162 - unsigned long clone_flags = args->flags; 162 + u64 clone_flags = args->flags; 163 163 unsigned long sp = args->stack; 164 164 unsigned long tls = args->tls; 165 165 struct inactive_task_frame *frame;
+1 -1
arch/x86/kernel/shstk.c
··· 191 191 current->thread.features_locked = 0; 192 192 } 193 193 194 - unsigned long shstk_alloc_thread_stack(struct task_struct *tsk, unsigned long clone_flags, 194 + unsigned long shstk_alloc_thread_stack(struct task_struct *tsk, u64 clone_flags, 195 195 unsigned long stack_size) 196 196 { 197 197 struct thread_shstk *shstk = &tsk->thread.shstk;
+1 -1
arch/xtensa/kernel/process.c
··· 267 267 268 268 int copy_thread(struct task_struct *p, const struct kernel_clone_args *args) 269 269 { 270 - unsigned long clone_flags = args->flags; 270 + u64 clone_flags = args->flags; 271 271 unsigned long usp_thread_fn = args->stack; 272 272 unsigned long tls = args->tls; 273 273 struct pt_regs *childregs = task_pt_regs(p);