Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1703272 > unrolled thread

Re: [PATCH v5 4/6] seccomp: Operation for checking if an action is available

Started byKees Cook <keescook@chromium.org>
First post2017-08-03 19:00 +0200
Last post2017-08-05 01:00 +0200
Articles 2 — 2 participants

Back to article view | Back to linux.kernel

This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by below is the oldest one visible, not the original post.


Contents

  Re: [PATCH v5 4/6] seccomp: Operation for checking if an action is available Kees Cook <keescook@chromium.org> - 2017-08-03 19:00 +0200
    Re: [PATCH v5 4/6] seccomp: Operation for checking if an action is  available Tyler Hicks <tyhicks@canonical.com> - 2017-08-05 01:00 +0200

#1703272 — Re: [PATCH v5 4/6] seccomp: Operation for checking if an action is available

FromKees Cook <keescook@chromium.org>
Date2017-08-03 19:00 +0200
SubjectRe: [PATCH v5 4/6] seccomp: Operation for checking if an action is available
Message-ID<uarDz-2I6-5@gated-at.bofh.it>
On Fri, Jul 28, 2017 at 1:55 PM, Tyler Hicks <tyhicks@canonical.com> wrote:
> 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>
> ---
>
> * Changes since v4:
>   - This is new patch to allow applications to check if an action is supported
>     without having to consult the actions_avail sysctl
>
>  include/uapi/linux/seccomp.h                  |  5 ++--
>  kernel/seccomp.c                              | 26 +++++++++++++++++++
>  tools/testing/selftests/seccomp/seccomp_bpf.c | 36 +++++++++++++++++++++++++++
>  3 files changed, 65 insertions(+), 2 deletions(-)
>
> diff --git a/include/uapi/linux/seccomp.h b/include/uapi/linux/seccomp.h
> index 82c823c..19a611d 100644
> --- a/include/uapi/linux/seccomp.h
> +++ b/include/uapi/linux/seccomp.h
> @@ -11,8 +11,9 @@
>  #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
> +#define SECCOMP_SET_MODE_STRICT                0
> +#define SECCOMP_SET_MODE_FILTER                1
> +#define SECCOMP_GET_ACTION_AVAIL       2
>
>  /* Valid flags for SECCOMP_SET_MODE_FILTER */
>  #define SECCOMP_FILTER_FLAG_TSYNC      1
> diff --git a/kernel/seccomp.c b/kernel/seccomp.c
> index 1c4c496..03ad3ba 100644
> --- a/kernel/seccomp.c
> +++ b/kernel/seccomp.c
> @@ -858,6 +858,27 @@ static inline long seccomp_set_mode_filter(unsigned int flags,
>  }
>  #endif
>
> +static long seccomp_get_action_avail(const char __user *uaction)
> +{
> +       u32 action;
> +
> +       if (copy_from_user(&action, uaction, sizeof(action)))
> +               return -EFAULT;
> +
> +       switch (action) {
> +       case SECCOMP_RET_KILL:
> +       case SECCOMP_RET_TRAP:
> +       case SECCOMP_RET_ERRNO:
> +       case SECCOMP_RET_TRACE:
> +       case SECCOMP_RET_ALLOW:
> +               break;
> +       default:
> +               return -EOPNOTSUPP;
> +       }
> +
> +       return 0;
> +}
> +
>  /* Common entry point for both prctl and syscall. */
>  static long do_seccomp(unsigned int op, unsigned int flags,
>                        const char __user *uargs)
> @@ -869,6 +890,11 @@ static long do_seccomp(unsigned int op, unsigned int flags,
>                 return seccomp_set_mode_strict();
>         case SECCOMP_SET_MODE_FILTER:
>                 return seccomp_set_mode_filter(flags, uargs);
> +       case SECCOMP_GET_ACTION_AVAIL:
> +               if (flags != 0)
> +                       return -EINVAL;
> +
> +               return seccomp_get_action_avail(uargs);
>         default:
>                 return -EINVAL;
>         }
> diff --git a/tools/testing/selftests/seccomp/seccomp_bpf.c b/tools/testing/selftests/seccomp/seccomp_bpf.c
> index eeb4f7a..8f0872b 100644
> --- a/tools/testing/selftests/seccomp/seccomp_bpf.c
> +++ b/tools/testing/selftests/seccomp/seccomp_bpf.c
> @@ -1683,6 +1683,10 @@ TEST_F_SIGNAL(TRACE_syscall, kill_after_ptrace, SIGSYS)
>  #define SECCOMP_SET_MODE_FILTER 1
>  #endif
>
> +#ifndef SECCOMP_GET_ACTION_AVAIL
> +#define SECCOMP_GET_ACTION_AVAIL 2
> +#endif
> +
>  #ifndef SECCOMP_FILTER_FLAG_TSYNC
>  #define SECCOMP_FILTER_FLAG_TSYNC 1
>  #endif
> @@ -2486,6 +2490,38 @@ TEST_SIGNAL(filter_flag_log, SIGSYS)
>         EXPECT_EQ(0, syscall(__NR_getpid));
>  }
>
> +TEST(get_action_avail)
> +{
> +       __u32 actions[] = { SECCOMP_RET_KILL,  SECCOMP_RET_TRAP,
> +                           SECCOMP_RET_ERRNO, SECCOMP_RET_TRACE,
> +                           SECCOMP_RET_ALLOW };
> +       __u32 unknown_action = 0x10000000U;
> +       int i;
> +       long ret;
> +
> +       ret = seccomp(SECCOMP_GET_ACTION_AVAIL, 0, &actions[0]);
> +       ASSERT_NE(ENOSYS, errno) {
> +               TH_LOG("Kernel does not support seccomp syscall!");
> +       }
> +       ASSERT_NE(EINVAL, errno) {
> +               TH_LOG("Kernel does not support SECCOMP_GET_ACTION_AVAIL operation!");
> +       }
> +       EXPECT_EQ(ret, 0);
> +
> +       for (i = 0; i < ARRAY_SIZE(actions); i++) {
> +               ret = seccomp(SECCOMP_GET_ACTION_AVAIL, 0, &actions[i]);
> +               EXPECT_EQ(ret, 0) {
> +                       TH_LOG("Expected action (0x%X) not available!",
> +                              actions[i]);
> +               }
> +       }
> +
> +       /* Check that an unknown action is handled properly (EOPNOTSUPP) */
> +       ret = seccomp(SECCOMP_GET_ACTION_AVAIL, 0, &unknown_action);
> +       EXPECT_EQ(ret, -1);
> +       EXPECT_EQ(errno, EOPNOTSUPP);
> +}
> +
>  /*
>   * TODO:
>   * - add microbenchmarks
> --
> 2.7.4
>

I like this a lot. I think it should follow the sysctl patch in the
series, but otherwise looks great.

-Kees

-- 
Kees Cook
Pixel Security

[toc] | [next] | [standalone]


#1704269 — Re: [PATCH v5 4/6] seccomp: Operation for checking if an action is available

FromTyler Hicks <tyhicks@canonical.com>
Date2017-08-05 01:00 +0200
SubjectRe: [PATCH v5 4/6] seccomp: Operation for checking if an action is available
Message-ID<uaTJv-4HY-9@gated-at.bofh.it>
In reply to#1703272

[Multipart message — attachments visible in raw view] — view raw

On 08/03/2017 11:54 AM, Kees Cook wrote:
> On Fri, Jul 28, 2017 at 1:55 PM, Tyler Hicks <tyhicks@canonical.com> wrote:
>> 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>
>> ---
>>
>> * Changes since v4:
>>   - This is new patch to allow applications to check if an action is supported
>>     without having to consult the actions_avail sysctl
>>
>>  include/uapi/linux/seccomp.h                  |  5 ++--
>>  kernel/seccomp.c                              | 26 +++++++++++++++++++
>>  tools/testing/selftests/seccomp/seccomp_bpf.c | 36 +++++++++++++++++++++++++++
>>  3 files changed, 65 insertions(+), 2 deletions(-)
>>
>> diff --git a/include/uapi/linux/seccomp.h b/include/uapi/linux/seccomp.h
>> index 82c823c..19a611d 100644
>> --- a/include/uapi/linux/seccomp.h
>> +++ b/include/uapi/linux/seccomp.h
>> @@ -11,8 +11,9 @@
>>  #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
>> +#define SECCOMP_SET_MODE_STRICT                0
>> +#define SECCOMP_SET_MODE_FILTER                1
>> +#define SECCOMP_GET_ACTION_AVAIL       2
>>
>>  /* Valid flags for SECCOMP_SET_MODE_FILTER */
>>  #define SECCOMP_FILTER_FLAG_TSYNC      1
>> diff --git a/kernel/seccomp.c b/kernel/seccomp.c
>> index 1c4c496..03ad3ba 100644
>> --- a/kernel/seccomp.c
>> +++ b/kernel/seccomp.c
>> @@ -858,6 +858,27 @@ static inline long seccomp_set_mode_filter(unsigned int flags,
>>  }
>>  #endif
>>
>> +static long seccomp_get_action_avail(const char __user *uaction)
>> +{
>> +       u32 action;
>> +
>> +       if (copy_from_user(&action, uaction, sizeof(action)))
>> +               return -EFAULT;
>> +
>> +       switch (action) {
>> +       case SECCOMP_RET_KILL:
>> +       case SECCOMP_RET_TRAP:
>> +       case SECCOMP_RET_ERRNO:
>> +       case SECCOMP_RET_TRACE:
>> +       case SECCOMP_RET_ALLOW:
>> +               break;
>> +       default:
>> +               return -EOPNOTSUPP;
>> +       }
>> +
>> +       return 0;
>> +}
>> +
>>  /* Common entry point for both prctl and syscall. */
>>  static long do_seccomp(unsigned int op, unsigned int flags,
>>                        const char __user *uargs)
>> @@ -869,6 +890,11 @@ static long do_seccomp(unsigned int op, unsigned int flags,
>>                 return seccomp_set_mode_strict();
>>         case SECCOMP_SET_MODE_FILTER:
>>                 return seccomp_set_mode_filter(flags, uargs);
>> +       case SECCOMP_GET_ACTION_AVAIL:
>> +               if (flags != 0)
>> +                       return -EINVAL;
>> +
>> +               return seccomp_get_action_avail(uargs);
>>         default:
>>                 return -EINVAL;
>>         }
>> diff --git a/tools/testing/selftests/seccomp/seccomp_bpf.c b/tools/testing/selftests/seccomp/seccomp_bpf.c
>> index eeb4f7a..8f0872b 100644
>> --- a/tools/testing/selftests/seccomp/seccomp_bpf.c
>> +++ b/tools/testing/selftests/seccomp/seccomp_bpf.c
>> @@ -1683,6 +1683,10 @@ TEST_F_SIGNAL(TRACE_syscall, kill_after_ptrace, SIGSYS)
>>  #define SECCOMP_SET_MODE_FILTER 1
>>  #endif
>>
>> +#ifndef SECCOMP_GET_ACTION_AVAIL
>> +#define SECCOMP_GET_ACTION_AVAIL 2
>> +#endif
>> +
>>  #ifndef SECCOMP_FILTER_FLAG_TSYNC
>>  #define SECCOMP_FILTER_FLAG_TSYNC 1
>>  #endif
>> @@ -2486,6 +2490,38 @@ TEST_SIGNAL(filter_flag_log, SIGSYS)
>>         EXPECT_EQ(0, syscall(__NR_getpid));
>>  }
>>
>> +TEST(get_action_avail)
>> +{
>> +       __u32 actions[] = { SECCOMP_RET_KILL,  SECCOMP_RET_TRAP,
>> +                           SECCOMP_RET_ERRNO, SECCOMP_RET_TRACE,
>> +                           SECCOMP_RET_ALLOW };
>> +       __u32 unknown_action = 0x10000000U;
>> +       int i;
>> +       long ret;
>> +
>> +       ret = seccomp(SECCOMP_GET_ACTION_AVAIL, 0, &actions[0]);
>> +       ASSERT_NE(ENOSYS, errno) {
>> +               TH_LOG("Kernel does not support seccomp syscall!");
>> +       }
>> +       ASSERT_NE(EINVAL, errno) {
>> +               TH_LOG("Kernel does not support SECCOMP_GET_ACTION_AVAIL operation!");
>> +       }
>> +       EXPECT_EQ(ret, 0);
>> +
>> +       for (i = 0; i < ARRAY_SIZE(actions); i++) {
>> +               ret = seccomp(SECCOMP_GET_ACTION_AVAIL, 0, &actions[i]);
>> +               EXPECT_EQ(ret, 0) {
>> +                       TH_LOG("Expected action (0x%X) not available!",
>> +                              actions[i]);
>> +               }
>> +       }
>> +
>> +       /* Check that an unknown action is handled properly (EOPNOTSUPP) */
>> +       ret = seccomp(SECCOMP_GET_ACTION_AVAIL, 0, &unknown_action);
>> +       EXPECT_EQ(ret, -1);
>> +       EXPECT_EQ(errno, EOPNOTSUPP);
>> +}
>> +
>>  /*
>>   * TODO:
>>   * - add microbenchmarks
>> --
>> 2.7.4
>>
> 
> I like this a lot. I think it should follow the sysctl patch in the
> series, but otherwise looks great.

Good to hear! I like it a lot, as well. I'm pretty sure Andy suggested
it so I'll add a Suggested-by tag in the next revision.

Tyler

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web