summaryrefslogtreecommitdiffstats
path: root/kernel/seccomp.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/seccomp.c')
-rw-r--r--kernel/seccomp.c16
1 files changed, 15 insertions, 1 deletions
diff --git a/kernel/seccomp.c b/kernel/seccomp.c
index 58125160417c..d5543e787e4e 100644
--- a/kernel/seccomp.c
+++ b/kernel/seccomp.c
@@ -199,6 +199,8 @@ static u32 seccomp_run_filters(int syscall)
static inline bool seccomp_may_assign_mode(unsigned long seccomp_mode)
{
+ BUG_ON(!spin_is_locked(&current->sighand->siglock));
+
if (current->seccomp.mode && current->seccomp.mode != seccomp_mode)
return false;
@@ -207,6 +209,8 @@ static inline bool seccomp_may_assign_mode(unsigned long seccomp_mode)
static inline void seccomp_assign_mode(unsigned long seccomp_mode)
{
+ BUG_ON(!spin_is_locked(&current->sighand->siglock));
+
current->seccomp.mode = seccomp_mode;
set_tsk_thread_flag(current, TIF_SECCOMP);
}
@@ -332,6 +336,8 @@ out:
* @flags: flags to change filter behavior
* @filter: seccomp filter to add to the current process
*
+ * Caller must be holding current->sighand->siglock lock.
+ *
* Returns 0 on success, -ve on error.
*/
static long seccomp_attach_filter(unsigned int flags,
@@ -340,6 +346,8 @@ static long seccomp_attach_filter(unsigned int flags,
unsigned long total_insns;
struct seccomp_filter *walker;
+ BUG_ON(!spin_is_locked(&current->sighand->siglock));
+
/* Validate resulting filter length. */
total_insns = filter->prog->len;
for (walker = current->seccomp.filter; walker; walker = walker->prev)
@@ -529,6 +537,8 @@ static long seccomp_set_mode_strict(void)
const unsigned long seccomp_mode = SECCOMP_MODE_STRICT;
long ret = -EINVAL;
+ spin_lock_irq(&current->sighand->siglock);
+
if (!seccomp_may_assign_mode(seccomp_mode))
goto out;
@@ -539,6 +549,7 @@ static long seccomp_set_mode_strict(void)
ret = 0;
out:
+ spin_unlock_irq(&current->sighand->siglock);
return ret;
}
@@ -566,13 +577,15 @@ static long seccomp_set_mode_filter(unsigned int flags,
/* Validate flags. */
if (flags != 0)
- goto out;
+ return -EINVAL;
/* Prepare the new filter before holding any locks. */
prepared = seccomp_prepare_user_filter(filter);
if (IS_ERR(prepared))
return PTR_ERR(prepared);
+ spin_lock_irq(&current->sighand->siglock);
+
if (!seccomp_may_assign_mode(seccomp_mode))
goto out;
@@ -584,6 +597,7 @@ static long seccomp_set_mode_filter(unsigned int flags,
seccomp_assign_mode(seccomp_mode);
out:
+ spin_unlock_irq(&current->sighand->siglock);
seccomp_filter_free(prepared);
return ret;
}