diff options
author | Tyler Hicks <tyhicks@canonical.com> | 2017-08-11 00:33:53 -0400 |
---|---|---|
committer | Kees Cook <keescook@chromium.org> | 2017-08-14 16:46:44 -0400 |
commit | d612b1fd8010d0d67b5287fe146b8b55bcbb8655 (patch) | |
tree | cadcaeebf71ffa28aced54e9fc8b7c0ee42cc6d3 /kernel | |
parent | 8e5f1ad116df6b0de65eac458d5e7c318d1c05af (diff) |
seccomp: Operation for checking if an action is available
Userspace code that needs to check if the kernel supports a given action
may not be able to use the /proc/sys/kernel/seccomp/actions_avail
sysctl. The process may be running in a sandbox and, therefore,
sufficient filesystem access may not be available. This patch adds an
operation to the seccomp(2) syscall that allows userspace code to ask
the kernel if a given action is available.
If the action is supported by the kernel, 0 is returned. If the action
is not supported by the kernel, -1 is returned with errno set to
-EOPNOTSUPP. If this check is attempted on a kernel that doesn't support
this new operation, -1 is returned with errno set to -EINVAL meaning
that userspace code will have the ability to differentiate between the
two error cases.
Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
Suggested-by: Andy Lutomirski <luto@amacapital.net>
Signed-off-by: Kees Cook <keescook@chromium.org>
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/seccomp.c | 26 |
1 files changed, 26 insertions, 0 deletions
diff --git a/kernel/seccomp.c b/kernel/seccomp.c index 5f19f41e4e50..7a6089f66fed 100644 --- a/kernel/seccomp.c +++ b/kernel/seccomp.c | |||
@@ -808,6 +808,27 @@ static inline long seccomp_set_mode_filter(unsigned int flags, | |||
808 | } | 808 | } |
809 | #endif | 809 | #endif |
810 | 810 | ||
811 | static long seccomp_get_action_avail(const char __user *uaction) | ||
812 | { | ||
813 | u32 action; | ||
814 | |||
815 | if (copy_from_user(&action, uaction, sizeof(action))) | ||
816 | return -EFAULT; | ||
817 | |||
818 | switch (action) { | ||
819 | case SECCOMP_RET_KILL: | ||
820 | case SECCOMP_RET_TRAP: | ||
821 | case SECCOMP_RET_ERRNO: | ||
822 | case SECCOMP_RET_TRACE: | ||
823 | case SECCOMP_RET_ALLOW: | ||
824 | break; | ||
825 | default: | ||
826 | return -EOPNOTSUPP; | ||
827 | } | ||
828 | |||
829 | return 0; | ||
830 | } | ||
831 | |||
811 | /* Common entry point for both prctl and syscall. */ | 832 | /* Common entry point for both prctl and syscall. */ |
812 | static long do_seccomp(unsigned int op, unsigned int flags, | 833 | static long do_seccomp(unsigned int op, unsigned int flags, |
813 | const char __user *uargs) | 834 | const char __user *uargs) |
@@ -819,6 +840,11 @@ static long do_seccomp(unsigned int op, unsigned int flags, | |||
819 | return seccomp_set_mode_strict(); | 840 | return seccomp_set_mode_strict(); |
820 | case SECCOMP_SET_MODE_FILTER: | 841 | case SECCOMP_SET_MODE_FILTER: |
821 | return seccomp_set_mode_filter(flags, uargs); | 842 | return seccomp_set_mode_filter(flags, uargs); |
843 | case SECCOMP_GET_ACTION_AVAIL: | ||
844 | if (flags != 0) | ||
845 | return -EINVAL; | ||
846 | |||
847 | return seccomp_get_action_avail(uargs); | ||
822 | default: | 848 | default: |
823 | return -EINVAL; | 849 | return -EINVAL; |
824 | } | 850 | } |