Merge 5.5-rc1 into android-mainline
Linux 5.5-rc1 Signed-off-by: Greg Kroah-Hartman <gregkh@google.com> Change-Id: I6f952ebdd40746115165a2f99bab340482f5c237
This commit is contained in:
149
kernel/fork.c
149
kernel/fork.c
@@ -40,7 +40,6 @@
|
||||
#include <linux/binfmts.h>
|
||||
#include <linux/mman.h>
|
||||
#include <linux/mmu_notifier.h>
|
||||
#include <linux/hmm.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/vmacache.h>
|
||||
@@ -93,9 +92,10 @@
|
||||
#include <linux/kcov.h>
|
||||
#include <linux/livepatch.h>
|
||||
#include <linux/thread_info.h>
|
||||
#include <linux/cpufreq_times.h>
|
||||
#include <linux/stackleak.h>
|
||||
#include <linux/scs.h>
|
||||
#include <linux/kasan.h>
|
||||
#include <linux/cpufreq_times.h>
|
||||
|
||||
#include <asm/pgtable.h>
|
||||
#include <asm/pgalloc.h>
|
||||
@@ -226,6 +226,9 @@ static unsigned long *alloc_thread_stack_node(struct task_struct *tsk, int node)
|
||||
if (!s)
|
||||
continue;
|
||||
|
||||
/* Clear the KASAN shadow of the stack. */
|
||||
kasan_unpoison_shadow(s->addr, THREAD_SIZE);
|
||||
|
||||
/* Clear stale pointers from reused stack. */
|
||||
memset(s->addr, 0, THREAD_SIZE);
|
||||
|
||||
@@ -1294,24 +1297,8 @@ static int wait_for_vfork_done(struct task_struct *child,
|
||||
* restoring the old one. . .
|
||||
* Eric Biederman 10 January 1998
|
||||
*/
|
||||
void mm_release(struct task_struct *tsk, struct mm_struct *mm)
|
||||
static void mm_release(struct task_struct *tsk, struct mm_struct *mm)
|
||||
{
|
||||
/* Get rid of any futexes when releasing the mm */
|
||||
#ifdef CONFIG_FUTEX
|
||||
if (unlikely(tsk->robust_list)) {
|
||||
exit_robust_list(tsk);
|
||||
tsk->robust_list = NULL;
|
||||
}
|
||||
#ifdef CONFIG_COMPAT
|
||||
if (unlikely(tsk->compat_robust_list)) {
|
||||
compat_exit_robust_list(tsk);
|
||||
tsk->compat_robust_list = NULL;
|
||||
}
|
||||
#endif
|
||||
if (unlikely(!list_empty(&tsk->pi_state_list)))
|
||||
exit_pi_state_list(tsk);
|
||||
#endif
|
||||
|
||||
uprobe_free_utask(tsk);
|
||||
|
||||
/* Get rid of any cached register state */
|
||||
@@ -1344,6 +1331,18 @@ void mm_release(struct task_struct *tsk, struct mm_struct *mm)
|
||||
complete_vfork_done(tsk);
|
||||
}
|
||||
|
||||
void exit_mm_release(struct task_struct *tsk, struct mm_struct *mm)
|
||||
{
|
||||
futex_exit_release(tsk);
|
||||
mm_release(tsk, mm);
|
||||
}
|
||||
|
||||
void exec_mm_release(struct task_struct *tsk, struct mm_struct *mm)
|
||||
{
|
||||
futex_exec_release(tsk);
|
||||
mm_release(tsk, mm);
|
||||
}
|
||||
|
||||
/**
|
||||
* dup_mm() - duplicates an existing mm structure
|
||||
* @tsk: the task_struct with which the new mm will be associated.
|
||||
@@ -1528,6 +1527,11 @@ static int copy_sighand(unsigned long clone_flags, struct task_struct *tsk)
|
||||
spin_lock_irq(¤t->sighand->siglock);
|
||||
memcpy(sig->action, current->sighand->action, sizeof(sig->action));
|
||||
spin_unlock_irq(¤t->sighand->siglock);
|
||||
|
||||
/* Reset all signal handler not set to SIG_IGN to SIG_DFL. */
|
||||
if (clone_flags & CLONE_CLEAR_SIGHAND)
|
||||
flush_signal_handlers(tsk, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1706,12 +1710,68 @@ static int pidfd_release(struct inode *inode, struct file *file)
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PROC_FS
|
||||
/**
|
||||
* pidfd_show_fdinfo - print information about a pidfd
|
||||
* @m: proc fdinfo file
|
||||
* @f: file referencing a pidfd
|
||||
*
|
||||
* Pid:
|
||||
* This function will print the pid that a given pidfd refers to in the
|
||||
* pid namespace of the procfs instance.
|
||||
* If the pid namespace of the process is not a descendant of the pid
|
||||
* namespace of the procfs instance 0 will be shown as its pid. This is
|
||||
* similar to calling getppid() on a process whose parent is outside of
|
||||
* its pid namespace.
|
||||
*
|
||||
* NSpid:
|
||||
* If pid namespaces are supported then this function will also print
|
||||
* the pid of a given pidfd refers to for all descendant pid namespaces
|
||||
* starting from the current pid namespace of the instance, i.e. the
|
||||
* Pid field and the first entry in the NSpid field will be identical.
|
||||
* If the pid namespace of the process is not a descendant of the pid
|
||||
* namespace of the procfs instance 0 will be shown as its first NSpid
|
||||
* entry and no others will be shown.
|
||||
* Note that this differs from the Pid and NSpid fields in
|
||||
* /proc/<pid>/status where Pid and NSpid are always shown relative to
|
||||
* the pid namespace of the procfs instance. The difference becomes
|
||||
* obvious when sending around a pidfd between pid namespaces from a
|
||||
* different branch of the tree, i.e. where no ancestoral relation is
|
||||
* present between the pid namespaces:
|
||||
* - create two new pid namespaces ns1 and ns2 in the initial pid
|
||||
* namespace (also take care to create new mount namespaces in the
|
||||
* new pid namespace and mount procfs)
|
||||
* - create a process with a pidfd in ns1
|
||||
* - send pidfd from ns1 to ns2
|
||||
* - read /proc/self/fdinfo/<pidfd> and observe that both Pid and NSpid
|
||||
* have exactly one entry, which is 0
|
||||
*/
|
||||
static void pidfd_show_fdinfo(struct seq_file *m, struct file *f)
|
||||
{
|
||||
struct pid_namespace *ns = proc_pid_ns(file_inode(m->file));
|
||||
struct pid *pid = f->private_data;
|
||||
struct pid_namespace *ns;
|
||||
pid_t nr = -1;
|
||||
|
||||
seq_put_decimal_ull(m, "Pid:\t", pid_nr_ns(pid, ns));
|
||||
if (likely(pid_has_task(pid, PIDTYPE_PID))) {
|
||||
ns = proc_pid_ns(file_inode(m->file));
|
||||
nr = pid_nr_ns(pid, ns);
|
||||
}
|
||||
|
||||
seq_put_decimal_ll(m, "Pid:\t", nr);
|
||||
|
||||
#ifdef CONFIG_PID_NS
|
||||
seq_put_decimal_ll(m, "\nNSpid:\t", nr);
|
||||
if (nr > 0) {
|
||||
int i;
|
||||
|
||||
/* If nr is non-zero it means that 'pid' is valid and that
|
||||
* ns, i.e. the pid namespace associated with the procfs
|
||||
* instance, is in the pid namespace hierarchy of pid.
|
||||
* Start at one below the already printed level.
|
||||
*/
|
||||
for (i = ns->level + 1; i <= pid->level; i++)
|
||||
seq_put_decimal_ll(m, "\t", pid->numbers[i].nr);
|
||||
}
|
||||
#endif
|
||||
seq_putc(m, '\n');
|
||||
}
|
||||
#endif
|
||||
@@ -2039,7 +2099,8 @@ static __latent_entropy struct task_struct *copy_process(
|
||||
stackleak_task_init(p);
|
||||
|
||||
if (pid != &init_struct_pid) {
|
||||
pid = alloc_pid(p->nsproxy->pid_ns_for_children);
|
||||
pid = alloc_pid(p->nsproxy->pid_ns_for_children, args->set_tid,
|
||||
args->set_tid_size);
|
||||
if (IS_ERR(pid)) {
|
||||
retval = PTR_ERR(pid);
|
||||
goto bad_fork_cleanup_thread;
|
||||
@@ -2075,14 +2136,8 @@ static __latent_entropy struct task_struct *copy_process(
|
||||
#ifdef CONFIG_BLOCK
|
||||
p->plug = NULL;
|
||||
#endif
|
||||
#ifdef CONFIG_FUTEX
|
||||
p->robust_list = NULL;
|
||||
#ifdef CONFIG_COMPAT
|
||||
p->compat_robust_list = NULL;
|
||||
#endif
|
||||
INIT_LIST_HEAD(&p->pi_state_list);
|
||||
p->pi_state_cache = NULL;
|
||||
#endif
|
||||
futex_init_task(p);
|
||||
|
||||
/*
|
||||
* sigaltstack should be cleared when sharing the same VM
|
||||
*/
|
||||
@@ -2143,7 +2198,7 @@ static __latent_entropy struct task_struct *copy_process(
|
||||
*/
|
||||
|
||||
p->start_time = ktime_get_ns();
|
||||
p->real_start_time = ktime_get_boottime_ns();
|
||||
p->start_boottime = ktime_get_boottime_ns();
|
||||
|
||||
/*
|
||||
* Make it visible to the rest of the system, but dont wake it up yet.
|
||||
@@ -2544,6 +2599,7 @@ noinline static int copy_clone_args_from_user(struct kernel_clone_args *kargs,
|
||||
{
|
||||
int err;
|
||||
struct clone_args args;
|
||||
pid_t *kset_tid = kargs->set_tid;
|
||||
|
||||
if (unlikely(usize > PAGE_SIZE))
|
||||
return -E2BIG;
|
||||
@@ -2554,6 +2610,15 @@ noinline static int copy_clone_args_from_user(struct kernel_clone_args *kargs,
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (unlikely(args.set_tid_size > MAX_PID_NS_LEVEL))
|
||||
return -EINVAL;
|
||||
|
||||
if (unlikely(!args.set_tid && args.set_tid_size > 0))
|
||||
return -EINVAL;
|
||||
|
||||
if (unlikely(args.set_tid && args.set_tid_size == 0))
|
||||
return -EINVAL;
|
||||
|
||||
/*
|
||||
* Verify that higher 32bits of exit_signal are unset and that
|
||||
* it is a valid signal
|
||||
@@ -2571,8 +2636,16 @@ noinline static int copy_clone_args_from_user(struct kernel_clone_args *kargs,
|
||||
.stack = args.stack,
|
||||
.stack_size = args.stack_size,
|
||||
.tls = args.tls,
|
||||
.set_tid_size = args.set_tid_size,
|
||||
};
|
||||
|
||||
if (args.set_tid &&
|
||||
copy_from_user(kset_tid, u64_to_user_ptr(args.set_tid),
|
||||
(kargs->set_tid_size * sizeof(pid_t))))
|
||||
return -EFAULT;
|
||||
|
||||
kargs->set_tid = kset_tid;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2606,11 +2679,8 @@ static inline bool clone3_stack_valid(struct kernel_clone_args *kargs)
|
||||
|
||||
static bool clone3_args_valid(struct kernel_clone_args *kargs)
|
||||
{
|
||||
/*
|
||||
* All lower bits of the flag word are taken.
|
||||
* Verify that no other unknown flags are passed along.
|
||||
*/
|
||||
if (kargs->flags & ~CLONE_LEGACY_FLAGS)
|
||||
/* Verify that no unknown flags are passed along. */
|
||||
if (kargs->flags & ~(CLONE_LEGACY_FLAGS | CLONE_CLEAR_SIGHAND))
|
||||
return false;
|
||||
|
||||
/*
|
||||
@@ -2620,6 +2690,10 @@ static bool clone3_args_valid(struct kernel_clone_args *kargs)
|
||||
if (kargs->flags & (CLONE_DETACHED | CSIGNAL))
|
||||
return false;
|
||||
|
||||
if ((kargs->flags & (CLONE_SIGHAND | CLONE_CLEAR_SIGHAND)) ==
|
||||
(CLONE_SIGHAND | CLONE_CLEAR_SIGHAND))
|
||||
return false;
|
||||
|
||||
if ((kargs->flags & (CLONE_THREAD | CLONE_PARENT)) &&
|
||||
kargs->exit_signal)
|
||||
return false;
|
||||
@@ -2646,6 +2720,9 @@ SYSCALL_DEFINE2(clone3, struct clone_args __user *, uargs, size_t, size)
|
||||
int err;
|
||||
|
||||
struct kernel_clone_args kargs;
|
||||
pid_t set_tid[MAX_PID_NS_LEVEL];
|
||||
|
||||
kargs.set_tid = set_tid;
|
||||
|
||||
err = copy_clone_args_from_user(&kargs, uargs, size);
|
||||
if (err)
|
||||
|
Reference in New Issue
Block a user