| From: Kees Cook <keescook@chromium.org> |
| Date: Wed, 25 Jun 2014 15:55:25 -0700 |
| Subject: seccomp: split mode setting routines |
| |
| commit 3b23dd12846215eff4afb073366b80c0c4d7543e upstream. |
| |
| Separates the two mode setting paths to make things more readable with |
| fewer #ifdefs within function bodies. |
| |
| Signed-off-by: Kees Cook <keescook@chromium.org> |
| Reviewed-by: Oleg Nesterov <oleg@redhat.com> |
| Reviewed-by: Andy Lutomirski <luto@amacapital.net> |
| Signed-off-by: Ben Hutchings <ben@decadent.org.uk> |
| --- |
| kernel/seccomp.c | 71 ++++++++++++++++++++++++++++++++---------------- |
| 1 file changed, 48 insertions(+), 23 deletions(-) |
| |
| --- a/kernel/seccomp.c |
| +++ b/kernel/seccomp.c |
| @@ -489,48 +489,66 @@ long prctl_get_seccomp(void) |
| } |
| |
| /** |
| - * seccomp_set_mode: internal function for setting seccomp mode |
| - * @seccomp_mode: requested mode to use |
| - * @filter: optional struct sock_fprog for use with SECCOMP_MODE_FILTER |
| - * |
| - * This function may be called repeatedly with a @seccomp_mode of |
| - * SECCOMP_MODE_FILTER to install additional filters. Every filter |
| - * successfully installed will be evaluated (in reverse order) for each system |
| - * call the task makes. |
| + * seccomp_set_mode_strict: internal function for setting strict seccomp |
| * |
| * Once current->seccomp.mode is non-zero, it may not be changed. |
| * |
| * Returns 0 on success or -EINVAL on failure. |
| */ |
| -static long seccomp_set_mode(unsigned long seccomp_mode, char __user *filter) |
| +static long seccomp_set_mode_strict(void) |
| { |
| + const unsigned long seccomp_mode = SECCOMP_MODE_STRICT; |
| long ret = -EINVAL; |
| |
| if (!seccomp_may_assign_mode(seccomp_mode)) |
| goto out; |
| |
| - switch (seccomp_mode) { |
| - case SECCOMP_MODE_STRICT: |
| - ret = 0; |
| #ifdef TIF_NOTSC |
| - disable_TSC(); |
| + disable_TSC(); |
| #endif |
| - break; |
| + seccomp_assign_mode(seccomp_mode); |
| + ret = 0; |
| + |
| +out: |
| + |
| + return ret; |
| +} |
| + |
| #ifdef CONFIG_SECCOMP_FILTER |
| - case SECCOMP_MODE_FILTER: |
| - ret = seccomp_attach_user_filter(filter); |
| - if (ret) |
| - goto out; |
| - break; |
| -#endif |
| - default: |
| +/** |
| + * seccomp_set_mode_filter: internal function for setting seccomp filter |
| + * @filter: struct sock_fprog containing filter |
| + * |
| + * This function may be called repeatedly to install additional filters. |
| + * Every filter successfully installed will be evaluated (in reverse order) |
| + * for each system call the task makes. |
| + * |
| + * Once current->seccomp.mode is non-zero, it may not be changed. |
| + * |
| + * Returns 0 on success or -EINVAL on failure. |
| + */ |
| +static long seccomp_set_mode_filter(char __user *filter) |
| +{ |
| + const unsigned long seccomp_mode = SECCOMP_MODE_FILTER; |
| + long ret = -EINVAL; |
| + |
| + if (!seccomp_may_assign_mode(seccomp_mode)) |
| + goto out; |
| + |
| + ret = seccomp_attach_user_filter(filter); |
| + if (ret) |
| goto out; |
| - } |
| |
| seccomp_assign_mode(seccomp_mode); |
| out: |
| return ret; |
| } |
| +#else |
| +static inline long seccomp_set_mode_filter(char __user *filter) |
| +{ |
| + return -EINVAL; |
| +} |
| +#endif |
| |
| /** |
| * prctl_set_seccomp: configures current->seccomp.mode |
| @@ -541,5 +559,12 @@ out: |
| */ |
| long prctl_set_seccomp(unsigned long seccomp_mode, char __user *filter) |
| { |
| - return seccomp_set_mode(seccomp_mode, filter); |
| + switch (seccomp_mode) { |
| + case SECCOMP_MODE_STRICT: |
| + return seccomp_set_mode_strict(); |
| + case SECCOMP_MODE_FILTER: |
| + return seccomp_set_mode_filter(filter); |
| + default: |
| + return -EINVAL; |
| + } |
| } |