Here's what we do here :
  - TIF_DISABLE_PTI_NOW is always cleared as we don't want an unprotected
    process to pass its lack of protection to any possible other program
    it could exec.

  - TIF_DISABLE_PTI_NEXT is copied into TIF_DISABLE_PTI_NOW and cleared,
    this is used by wrappers to disable PTI for a single exec call.

Thanks to this, PTI-aware programs can adjust TIF_DISABLE_PTI_NOW for
themselves, and a simple wrapper can be implemented by setting
TIF_DISABLE_PTI_NEXT to manage those unable to set TIF_DISABLE_PTI_NOW
themselves.

Signed-off-by: Willy Tarreau <[email protected]>
Cc: Andy Lutomirski <[email protected]>
Cc: Borislav Petkov <[email protected]>
Cc: Brian Gerst <[email protected]>
Cc: Dave Hansen <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Linus Torvalds <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Thomas Gleixner <[email protected]>
Cc: Josh Poimboeuf <[email protected]>
Cc: "H. Peter Anvin" <[email protected]>
Cc: Kees Cook <[email protected]>
Cc: Alexander Viro <[email protected]>
---
 fs/exec.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/fs/exec.c b/fs/exec.c
index 7eb8d21..cf42ddc 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -1814,6 +1814,16 @@ static int do_execveat_common(int fd, struct filename 
*filename,
        putname(filename);
        if (displaced)
                put_files_struct(displaced);
+
+#ifdef CONFIG_PER_PROCESS_PTI
+       /*
+        * TIF_DISABLE_PTI_NOW doesn't pass execve(). TIF_DISABLE_PTI_NEXT
+        * turns into TIF_DISABLE_PTI_NOW and disappears.
+        */
+       clear_thread_flag(TIF_DISABLE_PTI_NOW);
+       if (test_and_clear_thread_flag(TIF_DISABLE_PTI_NEXT))
+               set_thread_flag(TIF_DISABLE_PTI_NOW);
+#endif
        return retval;
 
 out:
-- 
1.7.12.1

Reply via email to