Skip to content

Commit

Permalink
Merge tag 'seccomp-3.17' of git://git.kernel.org/pub/scm/linux/kernel…
Browse files Browse the repository at this point in the history
…/git/kees/linux into next
  • Loading branch information
James Morris committed Jul 19, 2014
2 parents 2ccf466 + c2e1f2e commit fd33c43
Show file tree
Hide file tree
Showing 22 changed files with 471 additions and 80 deletions.
10 changes: 10 additions & 0 deletions MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -7953,6 +7953,16 @@ S: Maintained
F: drivers/mmc/host/sdhci.*
F: drivers/mmc/host/sdhci-pltfm.[ch]

SECURE COMPUTING
M: Kees Cook <[email protected]>
T: git git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git seccomp
S: Supported
F: kernel/seccomp.c
F: include/uapi/linux/seccomp.h
F: include/linux/seccomp.h
K: \bsecure_computing
K: \bTIF_SECCOMP\b

SECURE DIGITAL HOST CONTROLLER INTERFACE, OPEN FIRMWARE BINDINGS (SDHCI-OF)
M: Anton Vorontsov <[email protected]>
L: [email protected]
Expand Down
1 change: 1 addition & 0 deletions arch/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,7 @@ config HAVE_ARCH_SECCOMP_FILTER
- secure_computing is called from a ptrace_event()-safe context
- secure_computing return value is checked and a return value of -1
results in the system call being skipped immediately.
- seccomp syscall wired up

config SECCOMP_FILTER
def_bool y
Expand Down
1 change: 1 addition & 0 deletions arch/arm/include/uapi/asm/unistd.h
Original file line number Diff line number Diff line change
Expand Up @@ -409,6 +409,7 @@
#define __NR_sched_setattr (__NR_SYSCALL_BASE+380)
#define __NR_sched_getattr (__NR_SYSCALL_BASE+381)
#define __NR_renameat2 (__NR_SYSCALL_BASE+382)
#define __NR_seccomp (__NR_SYSCALL_BASE+383)

/*
* This may need to be greater than __NR_last_syscall+1 in order to
Expand Down
1 change: 1 addition & 0 deletions arch/arm/kernel/calls.S
Original file line number Diff line number Diff line change
Expand Up @@ -392,6 +392,7 @@
/* 380 */ CALL(sys_sched_setattr)
CALL(sys_sched_getattr)
CALL(sys_renameat2)
CALL(sys_seccomp)
#ifndef syscalls_counted
.equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls
#define syscalls_counted
Expand Down
15 changes: 9 additions & 6 deletions arch/mips/include/uapi/asm/unistd.h
Original file line number Diff line number Diff line change
Expand Up @@ -372,16 +372,17 @@
#define __NR_sched_setattr (__NR_Linux + 349)
#define __NR_sched_getattr (__NR_Linux + 350)
#define __NR_renameat2 (__NR_Linux + 351)
#define __NR_seccomp (__NR_Linux + 352)

/*
* Offset of the last Linux o32 flavoured syscall
*/
#define __NR_Linux_syscalls 351
#define __NR_Linux_syscalls 352

#endif /* _MIPS_SIM == _MIPS_SIM_ABI32 */

#define __NR_O32_Linux 4000
#define __NR_O32_Linux_syscalls 351
#define __NR_O32_Linux_syscalls 352

#if _MIPS_SIM == _MIPS_SIM_ABI64

Expand Down Expand Up @@ -701,16 +702,17 @@
#define __NR_sched_setattr (__NR_Linux + 309)
#define __NR_sched_getattr (__NR_Linux + 310)
#define __NR_renameat2 (__NR_Linux + 311)
#define __NR_seccomp (__NR_Linux + 312)

/*
* Offset of the last Linux 64-bit flavoured syscall
*/
#define __NR_Linux_syscalls 311
#define __NR_Linux_syscalls 312

#endif /* _MIPS_SIM == _MIPS_SIM_ABI64 */

#define __NR_64_Linux 5000
#define __NR_64_Linux_syscalls 311
#define __NR_64_Linux_syscalls 312

#if _MIPS_SIM == _MIPS_SIM_NABI32

Expand Down Expand Up @@ -1034,15 +1036,16 @@
#define __NR_sched_setattr (__NR_Linux + 313)
#define __NR_sched_getattr (__NR_Linux + 314)
#define __NR_renameat2 (__NR_Linux + 315)
#define __NR_seccomp (__NR_Linux + 316)

/*
* Offset of the last N32 flavoured syscall
*/
#define __NR_Linux_syscalls 315
#define __NR_Linux_syscalls 316

#endif /* _MIPS_SIM == _MIPS_SIM_NABI32 */

#define __NR_N32_Linux 6000
#define __NR_N32_Linux_syscalls 315
#define __NR_N32_Linux_syscalls 316

#endif /* _UAPI_ASM_UNISTD_H */
1 change: 1 addition & 0 deletions arch/mips/kernel/scall32-o32.S
Original file line number Diff line number Diff line change
Expand Up @@ -578,3 +578,4 @@ EXPORT(sys_call_table)
PTR sys_sched_setattr
PTR sys_sched_getattr /* 4350 */
PTR sys_renameat2
PTR sys_seccomp
1 change: 1 addition & 0 deletions arch/mips/kernel/scall64-64.S
Original file line number Diff line number Diff line change
Expand Up @@ -431,4 +431,5 @@ EXPORT(sys_call_table)
PTR sys_sched_setattr
PTR sys_sched_getattr /* 5310 */
PTR sys_renameat2
PTR sys_seccomp
.size sys_call_table,.-sys_call_table
1 change: 1 addition & 0 deletions arch/mips/kernel/scall64-n32.S
Original file line number Diff line number Diff line change
Expand Up @@ -424,4 +424,5 @@ EXPORT(sysn32_call_table)
PTR sys_sched_setattr
PTR sys_sched_getattr
PTR sys_renameat2 /* 6315 */
PTR sys_seccomp
.size sysn32_call_table,.-sysn32_call_table
1 change: 1 addition & 0 deletions arch/mips/kernel/scall64-o32.S
Original file line number Diff line number Diff line change
Expand Up @@ -557,4 +557,5 @@ EXPORT(sys32_call_table)
PTR sys_sched_setattr
PTR sys_sched_getattr /* 4350 */
PTR sys_renameat2
PTR sys_seccomp
.size sys32_call_table,.-sys32_call_table
1 change: 1 addition & 0 deletions arch/x86/syscalls/syscall_32.tbl
Original file line number Diff line number Diff line change
Expand Up @@ -360,3 +360,4 @@
351 i386 sched_setattr sys_sched_setattr
352 i386 sched_getattr sys_sched_getattr
353 i386 renameat2 sys_renameat2
354 i386 seccomp sys_seccomp
1 change: 1 addition & 0 deletions arch/x86/syscalls/syscall_64.tbl
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,7 @@
314 common sched_setattr sys_sched_setattr
315 common sched_getattr sys_sched_getattr
316 common renameat2 sys_renameat2
317 common seccomp sys_seccomp

#
# x32-specific system call numbers start at 512 to avoid cache impact
Expand Down
6 changes: 3 additions & 3 deletions fs/exec.c
Original file line number Diff line number Diff line change
Expand Up @@ -1216,7 +1216,7 @@ EXPORT_SYMBOL(install_exec_creds);
/*
* determine how safe it is to execute the proposed program
* - the caller must hold ->cred_guard_mutex to protect against
* PTRACE_ATTACH
* PTRACE_ATTACH or seccomp thread-sync
*/
static void check_unsafe_exec(struct linux_binprm *bprm)
{
Expand All @@ -1234,7 +1234,7 @@ static void check_unsafe_exec(struct linux_binprm *bprm)
* This isn't strictly necessary, but it makes it harder for LSMs to
* mess up.
*/
if (current->no_new_privs)
if (task_no_new_privs(current))
bprm->unsafe |= LSM_UNSAFE_NO_NEW_PRIVS;

t = p;
Expand Down Expand Up @@ -1272,7 +1272,7 @@ int prepare_binprm(struct linux_binprm *bprm)
bprm->cred->egid = current_egid();

if (!(bprm->file->f_path.mnt->mnt_flags & MNT_NOSUID) &&
!current->no_new_privs &&
!task_no_new_privs(current) &&
kuid_has_mapping(bprm->cred->user_ns, inode->i_uid) &&
kgid_has_mapping(bprm->cred->user_ns, inode->i_gid)) {
/* Set-uid? */
Expand Down
18 changes: 15 additions & 3 deletions include/linux/sched.h
Original file line number Diff line number Diff line change
Expand Up @@ -1307,13 +1307,12 @@ struct task_struct {
* execve */
unsigned in_iowait:1;

/* task may not gain privileges */
unsigned no_new_privs:1;

/* Revert to default priority/policy when forking */
unsigned sched_reset_on_fork:1;
unsigned sched_contributes_to_load:1;

unsigned long atomic_flags; /* Flags needing atomic access. */

pid_t pid;
pid_t tgid;

Expand Down Expand Up @@ -1967,6 +1966,19 @@ static inline void memalloc_noio_restore(unsigned int flags)
current->flags = (current->flags & ~PF_MEMALLOC_NOIO) | flags;
}

/* Per-process atomic flags. */
#define PFA_NO_NEW_PRIVS 0x00000001 /* May not gain new privileges. */

static inline bool task_no_new_privs(struct task_struct *p)
{
return test_bit(PFA_NO_NEW_PRIVS, &p->atomic_flags);
}

static inline void task_set_no_new_privs(struct task_struct *p)
{
set_bit(PFA_NO_NEW_PRIVS, &p->atomic_flags);
}

/*
* task->jobctl flags
*/
Expand Down
8 changes: 5 additions & 3 deletions include/linux/seccomp.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@

#include <uapi/linux/seccomp.h>

#define SECCOMP_FILTER_FLAG_MASK (SECCOMP_FILTER_FLAG_TSYNC)

#ifdef CONFIG_SECCOMP

#include <linux/thread_info.h>
Expand All @@ -14,11 +16,11 @@ struct seccomp_filter;
*
* @mode: indicates one of the valid values above for controlled
* system calls available to a process.
* @filter: The metadata and ruleset for determining what system calls
* are allowed for a task.
* @filter: must always point to a valid seccomp-filter or NULL as it is
* accessed without locking during system call entry.
*
* @filter must only be accessed from the context of current as there
* is no locking.
* is no read locking.
*/
struct seccomp {
int mode;
Expand Down
2 changes: 2 additions & 0 deletions include/linux/syscalls.h
Original file line number Diff line number Diff line change
Expand Up @@ -866,4 +866,6 @@ asmlinkage long sys_process_vm_writev(pid_t pid,
asmlinkage long sys_kcmp(pid_t pid1, pid_t pid2, int type,
unsigned long idx1, unsigned long idx2);
asmlinkage long sys_finit_module(int fd, const char __user *uargs, int flags);
asmlinkage long sys_seccomp(unsigned int op, unsigned int flags,
const char __user *uargs);
#endif
4 changes: 3 additions & 1 deletion include/uapi/asm-generic/unistd.h
Original file line number Diff line number Diff line change
Expand Up @@ -699,9 +699,11 @@ __SYSCALL(__NR_sched_setattr, sys_sched_setattr)
__SYSCALL(__NR_sched_getattr, sys_sched_getattr)
#define __NR_renameat2 276
__SYSCALL(__NR_renameat2, sys_renameat2)
#define __NR_seccomp 277
__SYSCALL(__NR_seccomp, sys_seccomp)

#undef __NR_syscalls
#define __NR_syscalls 277
#define __NR_syscalls 278

/*
* All syscalls below here should go away really,
Expand Down
7 changes: 7 additions & 0 deletions include/uapi/linux/seccomp.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,13 @@
#define SECCOMP_MODE_STRICT 1 /* uses hard-coded filter. */
#define SECCOMP_MODE_FILTER 2 /* uses user-supplied filter. */

/* Valid operations for seccomp syscall. */
#define SECCOMP_SET_MODE_STRICT 0
#define SECCOMP_SET_MODE_FILTER 1

/* Valid flags for SECCOMP_SET_MODE_FILTER */
#define SECCOMP_FILTER_FLAG_TSYNC 1

/*
* All BPF programs must return a 32-bit value.
* The bottom 16-bits are for optional return data.
Expand Down
49 changes: 48 additions & 1 deletion kernel/fork.c
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,15 @@ static struct task_struct *dup_task_struct(struct task_struct *orig)
goto free_ti;

tsk->stack = ti;
#ifdef CONFIG_SECCOMP
/*
* We must handle setting up seccomp filters once we're under
* the sighand lock in case orig has changed between now and
* then. Until then, filter must be NULL to avoid messing up
* the usage counts on the error path calling free_task.
*/
tsk->seccomp.filter = NULL;
#endif

setup_thread_stack(tsk, orig);
clear_user_return_notifier(tsk);
Expand Down Expand Up @@ -1081,6 +1090,39 @@ static int copy_signal(unsigned long clone_flags, struct task_struct *tsk)
return 0;
}

static void copy_seccomp(struct task_struct *p)
{
#ifdef CONFIG_SECCOMP
/*
* Must be called with sighand->lock held, which is common to
* all threads in the group. Holding cred_guard_mutex is not
* needed because this new task is not yet running and cannot
* be racing exec.
*/
BUG_ON(!spin_is_locked(&current->sighand->siglock));

/* Ref-count the new filter user, and assign it. */
get_seccomp_filter(current);
p->seccomp = current->seccomp;

/*
* Explicitly enable no_new_privs here in case it got set
* between the task_struct being duplicated and holding the
* sighand lock. The seccomp state and nnp must be in sync.
*/
if (task_no_new_privs(current))
task_set_no_new_privs(p);

/*
* If the parent gained a seccomp mode after copying thread
* flags and between before we held the sighand lock, we have
* to manually enable the seccomp thread flag here.
*/
if (p->seccomp.mode != SECCOMP_MODE_DISABLED)
set_tsk_thread_flag(p, TIF_SECCOMP);
#endif
}

SYSCALL_DEFINE1(set_tid_address, int __user *, tidptr)
{
current->clear_child_tid = tidptr;
Expand Down Expand Up @@ -1196,7 +1238,6 @@ static struct task_struct *copy_process(unsigned long clone_flags,
goto fork_out;

ftrace_graph_init_task(p);
get_seccomp_filter(p);

rt_mutex_init_task(p);

Expand Down Expand Up @@ -1436,6 +1477,12 @@ static struct task_struct *copy_process(unsigned long clone_flags,

spin_lock(&current->sighand->siglock);

/*
* Copy seccomp details explicitly here, in case they were changed
* before holding sighand lock.
*/
copy_seccomp(p);

/*
* Process group and session signals need to be delivered to just the
* parent before the fork or both the parent and the child after the
Expand Down
Loading

0 comments on commit fd33c43

Please sign in to comment.