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

Merge tag 'seccomp-next' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux into next

+31 -8
+1
include/linux/ptrace.h
··· 34 34 #define PT_TRACE_SECCOMP PT_EVENT_FLAG(PTRACE_EVENT_SECCOMP) 35 35 36 36 #define PT_EXITKILL (PTRACE_O_EXITKILL << PT_OPT_FLAG_SHIFT) 37 + #define PT_SUSPEND_SECCOMP (PTRACE_O_SUSPEND_SECCOMP << PT_OPT_FLAG_SHIFT) 37 38 38 39 /* single stepping state bits (used on ARM and PA-RISC) */ 39 40 #define PT_SINGLESTEP_BIT 31
+1 -1
include/linux/seccomp.h
··· 78 78 79 79 static inline int seccomp_mode(struct seccomp *s) 80 80 { 81 - return 0; 81 + return SECCOMP_MODE_DISABLED; 82 82 } 83 83 #endif /* CONFIG_SECCOMP */ 84 84
+4 -2
include/uapi/linux/ptrace.h
··· 89 89 #define PTRACE_O_TRACESECCOMP (1 << PTRACE_EVENT_SECCOMP) 90 90 91 91 /* eventless options */ 92 - #define PTRACE_O_EXITKILL (1 << 20) 92 + #define PTRACE_O_EXITKILL (1 << 20) 93 + #define PTRACE_O_SUSPEND_SECCOMP (1 << 21) 93 94 94 - #define PTRACE_O_MASK (0x000000ff | PTRACE_O_EXITKILL) 95 + #define PTRACE_O_MASK (\ 96 + 0x000000ff | PTRACE_O_EXITKILL | PTRACE_O_SUSPEND_SECCOMP) 95 97 96 98 #include <asm/ptrace.h> 97 99
+13
kernel/ptrace.c
··· 556 556 if (data & ~(unsigned long)PTRACE_O_MASK) 557 557 return -EINVAL; 558 558 559 + if (unlikely(data & PTRACE_O_SUSPEND_SECCOMP)) { 560 + if (!config_enabled(CONFIG_CHECKPOINT_RESTORE) || 561 + !config_enabled(CONFIG_SECCOMP)) 562 + return -EINVAL; 563 + 564 + if (!capable(CAP_SYS_ADMIN)) 565 + return -EPERM; 566 + 567 + if (seccomp_mode(&current->seccomp) != SECCOMP_MODE_DISABLED || 568 + current->ptrace & PT_SUSPEND_SECCOMP) 569 + return -EPERM; 570 + } 571 + 559 572 /* Avoid intermediate state when all opts are cleared */ 560 573 flags = child->ptrace; 561 574 flags &= ~(PTRACE_O_MASK << PT_OPT_FLAG_SHIFT);
+12 -5
kernel/seccomp.c
··· 175 175 */ 176 176 static u32 seccomp_run_filters(struct seccomp_data *sd) 177 177 { 178 - struct seccomp_filter *f = ACCESS_ONCE(current->seccomp.filter); 179 178 struct seccomp_data sd_local; 180 179 u32 ret = SECCOMP_RET_ALLOW; 180 + /* Make sure cross-thread synced filter points somewhere sane. */ 181 + struct seccomp_filter *f = 182 + lockless_dereference(current->seccomp.filter); 181 183 182 184 /* Ensure unexpected behavior doesn't result in failing open. */ 183 185 if (unlikely(WARN_ON(f == NULL))) 184 186 return SECCOMP_RET_KILL; 185 - 186 - /* Make sure cross-thread synced filter points somewhere sane. */ 187 - smp_read_barrier_depends(); 188 187 189 188 if (!sd) { 190 189 populate_seccomp_data(&sd_local); ··· 548 549 { 549 550 int mode = current->seccomp.mode; 550 551 551 - if (mode == 0) 552 + if (config_enabled(CONFIG_CHECKPOINT_RESTORE) && 553 + unlikely(current->ptrace & PT_SUSPEND_SECCOMP)) 554 + return; 555 + 556 + if (mode == SECCOMP_MODE_DISABLED) 552 557 return; 553 558 else if (mode == SECCOMP_MODE_STRICT) 554 559 __secure_computing_strict(this_syscall); ··· 652 649 int mode = current->seccomp.mode; 653 650 int this_syscall = sd ? sd->nr : 654 651 syscall_get_nr(current, task_pt_regs(current)); 652 + 653 + if (config_enabled(CONFIG_CHECKPOINT_RESTORE) && 654 + unlikely(current->ptrace & PT_SUSPEND_SECCOMP)) 655 + return SECCOMP_PHASE1_OK; 655 656 656 657 switch (mode) { 657 658 case SECCOMP_MODE_STRICT: