Merge remote-tracking branch 'sm8250/lineage-20' into lineage-23.2

* sm8250/lineage-20:
  UPSTREAM: arm64: Implement copy_thread_tls
  UPSTREAM: clone3: validate stack arguments
  UPSTREAM: clone3: switch to copy_struct_from_user()

Change-Id: I5580578220cbf78c7bf0b79cdadc548633bc9976
This commit is contained in:
Michael Bestas committed 2026-09-10 23:33:54 +03:00
commit 39bcecd5c6
3 files changed
+45 -33

No files matched your search

+1
View File
@@ -133,6 +133,7 @@ config ARM64
select HAVE_CMPXCHG_DOUBLE
select HAVE_CMPXCHG_LOCAL
select HAVE_CONTEXT_TRACKING
select HAVE_COPY_THREAD_TLS
select HAVE_DEBUG_BUGVERBOSE
select HAVE_DEBUG_KMEMLEAK
select HAVE_DMA_CONTIGUOUS
+5 -5
View File
@@ -394,8 +394,8 @@ int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src)
asmlinkage void ret_from_fork(void) asm("ret_from_fork");
int copy_thread(unsigned long clone_flags, unsigned long stack_start,
unsigned long stk_sz, struct task_struct *p)
int copy_thread_tls(unsigned long clone_flags, unsigned long stack_start,
unsigned long stk_sz, struct task_struct *p, unsigned long tls)
{
struct pt_regs *childregs = task_pt_regs(p);
@@ -428,11 +428,11 @@ int copy_thread(unsigned long clone_flags, unsigned long stack_start,
}
/*
* If a TLS pointer was passed to clone (4th argument), use it
* for the new thread.
* If a TLS pointer was passed to clone, use it for the new
* thread.
*/
if (clone_flags & CLONE_SETTLS)
p->thread.uw.tp_value = childregs->regs[3];
p->thread.uw.tp_value = tls;
} else {
memset(childregs, 0, sizeof(struct pt_regs));
childregs->pstate = PSR_MODE_EL1h;
+39 -28
View File
@@ -2561,40 +2561,20 @@ SYSCALL_DEFINE5(clone, unsigned long, clone_flags, unsigned long, newsp,
#ifdef __ARCH_WANT_SYS_CLONE3
noinline static int copy_clone_args_from_user(struct kernel_clone_args *kargs,
struct clone_args __user *uargs,
size_t size)
size_t usize)
{
int err;
struct clone_args args;
pid_t *kset_tid = kargs->set_tid;
if (unlikely(size > PAGE_SIZE))
if (unlikely(usize > PAGE_SIZE))
return -E2BIG;
if (unlikely(size < sizeof(struct clone_args)))
if (unlikely(usize < CLONE_ARGS_SIZE_VER0))
return -EINVAL;
if (unlikely(!access_ok(VERIFY_READ, uargs, size)))
return -EFAULT;
if (size > sizeof(struct clone_args)) {
unsigned char __user *addr;
unsigned char __user *end;
unsigned char val;
addr = (void __user *)uargs + sizeof(struct clone_args);
end = (void __user *)uargs + size;
for (; addr < end; addr++) {
if (get_user(val, addr))
return -EFAULT;
if (val)
return -E2BIG;
}
size = sizeof(struct clone_args);
}
if (copy_from_user(&args, uargs, size))
return -EFAULT;
err = copy_struct_from_user(&args, sizeof(args), uargs, usize);
if (err)
return err;
if (unlikely(args.set_tid_size > MAX_PID_NS_LEVEL))
return -EINVAL;
@@ -2635,7 +2615,35 @@ noinline static int copy_clone_args_from_user(struct kernel_clone_args *kargs,
return 0;
}
static bool clone3_args_valid(const struct kernel_clone_args *kargs)
/**
* clone3_stack_valid - check and prepare stack
* @kargs: kernel clone args
*
* Verify that the stack arguments userspace gave us are sane.
* In addition, set the stack direction for userspace since it's easy for us to
* determine.
*/
static inline bool clone3_stack_valid(struct kernel_clone_args *kargs)
{
if (kargs->stack == 0) {
if (kargs->stack_size > 0)
return false;
} else {
if (kargs->stack_size == 0)
return false;
if (!access_ok(VERIFY_WRITE, (void __user *)kargs->stack, kargs->stack_size))
return false;
#if !defined(CONFIG_STACK_GROWSUP) && !defined(CONFIG_IA64)
kargs->stack += kargs->stack_size;
#endif
}
return true;
}
static bool clone3_args_valid(struct kernel_clone_args *kargs)
{
/* Verify that no unknown flags are passed along. */
if (kargs->flags & ~(CLONE_LEGACY_FLAGS | CLONE_CLEAR_SIGHAND))
@@ -2656,6 +2664,9 @@ static bool clone3_args_valid(const struct kernel_clone_args *kargs)
kargs->exit_signal)
return false;
if (!clone3_stack_valid(kargs))
return false;
return true;
}