|
@@ -199,6 +199,8 @@ static u32 seccomp_run_filters(int syscall)
|
|
|
|
|
|
static inline bool seccomp_may_assign_mode(unsigned long seccomp_mode)
|
|
static inline bool seccomp_may_assign_mode(unsigned long seccomp_mode)
|
|
{
|
|
{
|
|
|
|
+ BUG_ON(!spin_is_locked(¤t->sighand->siglock));
|
|
|
|
+
|
|
if (current->seccomp.mode && current->seccomp.mode != seccomp_mode)
|
|
if (current->seccomp.mode && current->seccomp.mode != seccomp_mode)
|
|
return false;
|
|
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)
|
|
static inline void seccomp_assign_mode(unsigned long seccomp_mode)
|
|
{
|
|
{
|
|
|
|
+ BUG_ON(!spin_is_locked(¤t->sighand->siglock));
|
|
|
|
+
|
|
current->seccomp.mode = seccomp_mode;
|
|
current->seccomp.mode = seccomp_mode;
|
|
set_tsk_thread_flag(current, TIF_SECCOMP);
|
|
set_tsk_thread_flag(current, TIF_SECCOMP);
|
|
}
|
|
}
|
|
@@ -332,6 +336,8 @@ out:
|
|
* @flags: flags to change filter behavior
|
|
* @flags: flags to change filter behavior
|
|
* @filter: seccomp filter to add to the current process
|
|
* @filter: seccomp filter to add to the current process
|
|
*
|
|
*
|
|
|
|
+ * Caller must be holding current->sighand->siglock lock.
|
|
|
|
+ *
|
|
* Returns 0 on success, -ve on error.
|
|
* Returns 0 on success, -ve on error.
|
|
*/
|
|
*/
|
|
static long seccomp_attach_filter(unsigned int flags,
|
|
static long seccomp_attach_filter(unsigned int flags,
|
|
@@ -340,6 +346,8 @@ static long seccomp_attach_filter(unsigned int flags,
|
|
unsigned long total_insns;
|
|
unsigned long total_insns;
|
|
struct seccomp_filter *walker;
|
|
struct seccomp_filter *walker;
|
|
|
|
|
|
|
|
+ BUG_ON(!spin_is_locked(¤t->sighand->siglock));
|
|
|
|
+
|
|
/* Validate resulting filter length. */
|
|
/* Validate resulting filter length. */
|
|
total_insns = filter->prog->len;
|
|
total_insns = filter->prog->len;
|
|
for (walker = current->seccomp.filter; walker; walker = walker->prev)
|
|
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;
|
|
const unsigned long seccomp_mode = SECCOMP_MODE_STRICT;
|
|
long ret = -EINVAL;
|
|
long ret = -EINVAL;
|
|
|
|
|
|
|
|
+ spin_lock_irq(¤t->sighand->siglock);
|
|
|
|
+
|
|
if (!seccomp_may_assign_mode(seccomp_mode))
|
|
if (!seccomp_may_assign_mode(seccomp_mode))
|
|
goto out;
|
|
goto out;
|
|
|
|
|
|
@@ -539,6 +549,7 @@ static long seccomp_set_mode_strict(void)
|
|
ret = 0;
|
|
ret = 0;
|
|
|
|
|
|
out:
|
|
out:
|
|
|
|
+ spin_unlock_irq(¤t->sighand->siglock);
|
|
|
|
|
|
return ret;
|
|
return ret;
|
|
}
|
|
}
|
|
@@ -566,13 +577,15 @@ static long seccomp_set_mode_filter(unsigned int flags,
|
|
|
|
|
|
/* Validate flags. */
|
|
/* Validate flags. */
|
|
if (flags != 0)
|
|
if (flags != 0)
|
|
- goto out;
|
|
|
|
|
|
+ return -EINVAL;
|
|
|
|
|
|
/* Prepare the new filter before holding any locks. */
|
|
/* Prepare the new filter before holding any locks. */
|
|
prepared = seccomp_prepare_user_filter(filter);
|
|
prepared = seccomp_prepare_user_filter(filter);
|
|
if (IS_ERR(prepared))
|
|
if (IS_ERR(prepared))
|
|
return PTR_ERR(prepared);
|
|
return PTR_ERR(prepared);
|
|
|
|
|
|
|
|
+ spin_lock_irq(¤t->sighand->siglock);
|
|
|
|
+
|
|
if (!seccomp_may_assign_mode(seccomp_mode))
|
|
if (!seccomp_may_assign_mode(seccomp_mode))
|
|
goto out;
|
|
goto out;
|
|
|
|
|
|
@@ -584,6 +597,7 @@ static long seccomp_set_mode_filter(unsigned int flags,
|
|
|
|
|
|
seccomp_assign_mode(seccomp_mode);
|
|
seccomp_assign_mode(seccomp_mode);
|
|
out:
|
|
out:
|
|
|
|
+ spin_unlock_irq(¤t->sighand->siglock);
|
|
seccomp_filter_free(prepared);
|
|
seccomp_filter_free(prepared);
|
|
return ret;
|
|
return ret;
|
|
}
|
|
}
|