OSDN Git Service

Merge tag 'x86_shstk_for_6.6-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git...
[tomoyo/tomoyo-test1.git] / arch / x86 / kernel / process.c
index 72015db..9f09091 100644 (file)
@@ -51,6 +51,7 @@
 #include <asm/unwind.h>
 #include <asm/tdx.h>
 #include <asm/mmu_context.h>
+#include <asm/shstk.h>
 
 #include "process.h"
 
@@ -122,6 +123,7 @@ void exit_thread(struct task_struct *tsk)
 
        free_vm86(t);
 
+       shstk_free(tsk);
        fpu__drop(fpu);
 }
 
@@ -162,6 +164,7 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
        struct inactive_task_frame *frame;
        struct fork_frame *fork_frame;
        struct pt_regs *childregs;
+       unsigned long new_ssp;
        int ret = 0;
 
        childregs = task_pt_regs(p);
@@ -199,7 +202,16 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
        frame->flags = X86_EFLAGS_FIXED;
 #endif
 
-       fpu_clone(p, clone_flags, args->fn);
+       /*
+        * Allocate a new shadow stack for thread if needed. If shadow stack,
+        * is disabled, new_ssp will remain 0, and fpu_clone() will know not to
+        * update it.
+        */
+       new_ssp = shstk_alloc_thread_stack(p, clone_flags, args->stack_size);
+       if (IS_ERR_VALUE(new_ssp))
+               return PTR_ERR((void *)new_ssp);
+
+       fpu_clone(p, clone_flags, args->fn, new_ssp);
 
        /* Kernel thread ? */
        if (unlikely(p->flags & PF_KTHREAD)) {
@@ -245,6 +257,13 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
        if (!ret && unlikely(test_tsk_thread_flag(current, TIF_IO_BITMAP)))
                io_bitmap_share(p);
 
+       /*
+        * If copy_thread() if failing, don't leak the shadow stack possibly
+        * allocated in shstk_alloc_thread_stack() above.
+        */
+       if (ret)
+               shstk_free(p);
+
        return ret;
 }