All of lore.kernel.org
 help / color / mirror / Atom feed
From: Kees Cook <kees@kernel.org>
To: Alexander Mikhalitsyn <aleksandr.mikhalitsyn@canonical.com>
Cc: linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org,
	"Andy Lutomirski" <luto@amacapital.net>,
	"Will Drewry" <wad@chromium.org>,
	"Jonathan Corbet" <corbet@lwn.net>,
	"Shuah Khan" <shuah@kernel.org>,
	"Tycho Andersen" <tycho@tycho.pizza>,
	"Andrei Vagin" <avagin@gmail.com>,
	"Christian Brauner" <brauner@kernel.org>,
	"Stéphane Graber" <stgraber@stgraber.org>
Subject: Re: [PATCH v1 2/6] seccomp: prepare seccomp_run_filters() to support more than one listener
Date: Tue, 2 Dec 2025 12:26:46 -0800	[thread overview]
Message-ID: <202512021222.752619D@keescook> (raw)
In-Reply-To: <20251201122406.105045-3-aleksandr.mikhalitsyn@canonical.com>

On Mon, Dec 01, 2025 at 01:23:59PM +0100, Alexander Mikhalitsyn wrote:
> Prepare seccomp_run_filters() function to support more than one listener
> in the seccomp tree. In this patch, we only introduce a new
> struct seccomp_filter_matches with kdoc and modify seccomp_run_filters()
> signature correspondingly.
> 
> No functional change intended.
> 
> Cc: linux-doc@vger.kernel.org
> Cc: linux-kernel@vger.kernel.org
> Cc: Kees Cook <kees@kernel.org>
> Cc: Andy Lutomirski <luto@amacapital.net>
> Cc: Will Drewry <wad@chromium.org>
> Cc: Jonathan Corbet <corbet@lwn.net>
> Cc: Shuah Khan <shuah@kernel.org>
> Cc: Tycho Andersen <tycho@tycho.pizza>
> Cc: Andrei Vagin <avagin@gmail.com>
> Cc: Christian Brauner <brauner@kernel.org>
> Cc: Stéphane Graber <stgraber@stgraber.org>
> Signed-off-by: Alexander Mikhalitsyn <aleksandr.mikhalitsyn@canonical.com>
> ---
>  kernel/seccomp.c | 35 +++++++++++++++++++++++++++++++----
>  1 file changed, 31 insertions(+), 4 deletions(-)
> 
> diff --git a/kernel/seccomp.c b/kernel/seccomp.c
> index f944ea5a2716..c9a1062a53bd 100644
> --- a/kernel/seccomp.c
> +++ b/kernel/seccomp.c
> @@ -237,6 +237,9 @@ struct seccomp_filter {
>  /* Limit any path through the tree to 256KB worth of instructions. */
>  #define MAX_INSNS_PER_PATH ((1 << 18) / sizeof(struct sock_filter))
>  
> +/* Limit number of listeners through the tree. */
> +#define MAX_LISTENERS_PER_PATH 8
> +
>  /*
>   * Endianness is explicitly ignored and left for BPF program authors to manage
>   * as per the specific architecture.
> @@ -391,18 +394,38 @@ static inline bool seccomp_cache_check_allow(const struct seccomp_filter *sfilte
>  }
>  #endif /* SECCOMP_ARCH_NATIVE */
>  
> +/**
> + * struct seccomp_filter_matches - container for seccomp filter match results
> + *
> + * @n: A number of filters matched.
> + * @filters: An array of (struct seccomp_filter) pointers.
> + *	     Holds pointers to filters that matched during evaluation.
> + *	     A first one in the array is the one with the least permissive
> + *	     action result.
> + *
> + * If final action result is less (or more) permissive than SECCOMP_RET_USER_NOTIF,
> + * only the most restrictive filter is stored in the array's first element.
> + * If final action result is SECCOMP_RET_USER_NOTIF, we need to track
> + * all filters that resulted in the same action to support multiple listeners
> + * in seccomp tree.
> + */
> +struct seccomp_filter_matches {
> +	unsigned char n;
> +	struct seccomp_filter *filters[MAX_LISTENERS_PER_PATH];
> +};
> +
>  #define ACTION_ONLY(ret) ((s32)((ret) & (SECCOMP_RET_ACTION_FULL)))
>  /**
>   * seccomp_run_filters - evaluates all seccomp filters against @sd
>   * @sd: optional seccomp data to be passed to filters
> - * @match: stores struct seccomp_filter that resulted in the return value,
> + * @matches: array of struct seccomp_filter pointers that resulted in the return value,
>   *         unless filter returned SECCOMP_RET_ALLOW, in which case it will
>   *         be unchanged.
>   *
>   * Returns valid seccomp BPF response codes.
>   */
>  static u32 seccomp_run_filters(const struct seccomp_data *sd,
> -			       struct seccomp_filter **match)
> +			       struct seccomp_filter_matches *matches)
>  {
>  	u32 ret = SECCOMP_RET_ALLOW;
>  	/* Make sure cross-thread synced filter points somewhere sane. */
> @@ -425,7 +448,8 @@ static u32 seccomp_run_filters(const struct seccomp_data *sd,
>  
>  		if (ACTION_ONLY(cur_ret) < ACTION_ONLY(ret)) {
>  			ret = cur_ret;
> -			*match = f;
> +			matches->n = 1;
> +			matches->filters[0] = f;
>  		}
>  	}
>  	return ret;
> @@ -1252,6 +1276,7 @@ static int __seccomp_filter(int this_syscall, const bool recheck_after_trace)
>  {
>  	u32 filter_ret, action;
>  	struct seccomp_data sd;
> +	struct seccomp_filter_matches matches = {};

I was surprised to see this didn't induce a stack protector check (due
to the array use). It does, however, expand the work done to clear local
variables (i.e. this adds 9 unsigned long zeroings to the default case).

Regardless, I'll read this thread more closely in time for the LPC
session; I'm not exactly opposed to allowing multiple listeners, but I
do want to meditate on the safety logic (which I see you've spent time
thinking about too).

Thanks!

-Kees

-- 
Kees Cook

  parent reply	other threads:[~2025-12-02 20:26 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-12-01 12:23 [PATCH v1 0/6] seccomp: support nested listeners Alexander Mikhalitsyn
2025-12-01 12:23 ` [PATCH v1 1/6] seccomp: remove unused argument from seccomp_do_user_notification Alexander Mikhalitsyn
2025-12-01 14:19   ` Tycho Andersen
2025-12-02 11:56     ` Aleksandr Mikhalitsyn
2025-12-01 12:23 ` [PATCH v1 2/6] seccomp: prepare seccomp_run_filters() to support more than one listener Alexander Mikhalitsyn
2025-12-01 14:24   ` Tycho Andersen
2025-12-02 11:58     ` Aleksandr Mikhalitsyn
2025-12-02 14:06       ` Tycho Andersen
2025-12-02 20:26   ` Kees Cook [this message]
2025-12-03 15:25     ` Aleksandr Mikhalitsyn
2025-12-01 12:24 ` [PATCH v1 3/6] seccomp: limit number of listeners in seccomp tree Alexander Mikhalitsyn
2025-12-01 12:24 ` [PATCH v1 4/6] seccomp: handle multiple listeners case Alexander Mikhalitsyn
2025-12-01 14:38   ` Tycho Andersen
2025-12-02 12:01     ` Aleksandr Mikhalitsyn
2025-12-01 12:24 ` [PATCH v1 5/6] seccomp: relax has_duplicate_listeners check Alexander Mikhalitsyn
2025-12-01 12:24 ` [PATCH v1 6/6] tools/testing/selftests/seccomp: test nested listeners Alexander Mikhalitsyn

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=202512021222.752619D@keescook \
    --to=kees@kernel.org \
    --cc=aleksandr.mikhalitsyn@canonical.com \
    --cc=avagin@gmail.com \
    --cc=brauner@kernel.org \
    --cc=corbet@lwn.net \
    --cc=linux-doc@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=luto@amacapital.net \
    --cc=shuah@kernel.org \
    --cc=stgraber@stgraber.org \
    --cc=tycho@tycho.pizza \
    --cc=wad@chromium.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.