From: "Mickaël Salaün" <mic@digikod.net>
To: Tahera Fahimi <fahimitahera@gmail.com>
Cc: outreachy@lists.linux.dev, gnoack@google.com,
paul@paul-moore.com, jmorris@namei.org, serge@hallyn.com,
linux-security-module@vger.kernel.org,
linux-kernel@vger.kernel.org, bjorn3_gh@protonmail.com,
jannh@google.com, netdev@vger.kernel.org
Subject: Re: [PATCH v10 5/6] sample/Landlock: Support abstract unix socket restriction
Date: Wed, 21 Aug 2024 17:59:07 +0200 [thread overview]
Message-ID: <20240821.Ohph8see3ru2@digikod.net> (raw)
In-Reply-To: <72945c1bf5ad016642b678764f44a3dcc5cb040b.1724125513.git.fahimitahera@gmail.com>
On Mon, Aug 19, 2024 at 10:08:55PM -0600, Tahera Fahimi wrote:
> A sandboxer can receive the character "a" as input from the environment
> variable LL_SCOPE to restrict the abstract UNIX sockets from connecting
> to a process outside its scoped domain.
>
> Example
> =======
> Create an abstract unix socket to listen with socat(1):
> socat abstract-listen:mysocket -
>
> Create a sandboxed shell and pass the character "a" to LL_SCOPED:
> LL_FS_RO=/ LL_FS_RW=. LL_SCOPED="a" ./sandboxer /bin/bash
>
> If the sandboxed process tries to connect to the listening socket
> with command "socat - abstract-connect:mysocket", the connection
> will fail.
>
> Signed-off-by: Tahera Fahimi <fahimitahera@gmail.com>
> ---
> v10:
> - Minor improvement in code based on v9.
> v9:
> - Add a restrict approach on input of LL_SCOPED, so it only allows zero
> or one "a" to be the input.
> v8:
> - Adding check_ruleset_scope function to parse the scope environment
> variable and update the landlock attribute based on the restriction
> provided by the user.
> - Adding Mickaël Salaün reviews on version 7.
>
> v7:
> - Adding IPC scoping to the sandbox demo by defining a new "LL_SCOPED"
> environment variable. "LL_SCOPED" gets value "a" to restrict abstract
> unix sockets.
> - Change LANDLOCK_ABI_LAST to 6.
> ---
> samples/landlock/sandboxer.c | 56 +++++++++++++++++++++++++++++++++---
> 1 file changed, 52 insertions(+), 4 deletions(-)
>
> diff --git a/samples/landlock/sandboxer.c b/samples/landlock/sandboxer.c
> index e8223c3e781a..0564d0a40c67 100644
> --- a/samples/landlock/sandboxer.c
> +++ b/samples/landlock/sandboxer.c
> @@ -14,6 +14,7 @@
> #include <fcntl.h>
> #include <linux/landlock.h>
> #include <linux/prctl.h>
> +#include <linux/socket.h>
> #include <stddef.h>
> #include <stdio.h>
> #include <stdlib.h>
> @@ -22,6 +23,7 @@
> #include <sys/stat.h>
> #include <sys/syscall.h>
> #include <unistd.h>
> +#include <stdbool.h>
>
> #ifndef landlock_create_ruleset
> static inline int
> @@ -55,6 +57,7 @@ static inline int landlock_restrict_self(const int ruleset_fd,
> #define ENV_FS_RW_NAME "LL_FS_RW"
> #define ENV_TCP_BIND_NAME "LL_TCP_BIND"
> #define ENV_TCP_CONNECT_NAME "LL_TCP_CONNECT"
> +#define ENV_SCOPED_NAME "LL_SCOPED"
> #define ENV_DELIMITER ":"
>
> static int parse_path(char *env_path, const char ***const path_list)
> @@ -184,6 +187,40 @@ static int populate_ruleset_net(const char *const env_var, const int ruleset_fd,
> return ret;
> }
>
> +static bool check_ruleset_scope(const char *const env_var,
> + struct landlock_ruleset_attr *ruleset_attr)
> +{
> + bool abstract_scoping = false;
> + bool ret = true;
> + char *env_type_scope, *env_type_scope_next, *ipc_scoping_name;
> +
> + ruleset_attr->scoped &= ~LANDLOCK_SCOPED_ABSTRACT_UNIX_SOCKET;
This is bug prone because it removes the scope flags but doesn't store
the initial state. It would be better to use the abstract_scoping
variable to unset the related flag at the end of this function.
> + env_type_scope = getenv(env_var);
> + /* scoping is not supported by the user */
> + if (!env_type_scope || strcmp("", env_type_scope) == 0)
> + return true;
> +
> + env_type_scope = strdup(env_type_scope);
> + unsetenv(env_var);
> + env_type_scope_next = env_type_scope;
> + while ((ipc_scoping_name =
> + strsep(&env_type_scope_next, ENV_DELIMITER))) {
> + if (strcmp("a", ipc_scoping_name) == 0 && !abstract_scoping) {
> + abstract_scoping = true;
> + ruleset_attr->scoped |=
> + LANDLOCK_SCOPED_ABSTRACT_UNIX_SOCKET;
> + } else {
> + fprintf(stderr, "Unsupported scoping \"%s\"\n",
> + ipc_scoping_name);
> + ret = false;
> + goto out_free_name;
> + }
> + }
> +out_free_name:
> + free(env_type_scope);
> + return ret;
> +}
> +
> /* clang-format off */
>
> #define ACCESS_FS_ROUGHLY_READ ( \
> @@ -208,7 +245,7 @@ static int populate_ruleset_net(const char *const env_var, const int ruleset_fd,
>
> /* clang-format on */
>
> -#define LANDLOCK_ABI_LAST 5
> +#define LANDLOCK_ABI_LAST 6
>
> int main(const int argc, char *const argv[], char *const *const envp)
> {
> @@ -223,14 +260,15 @@ int main(const int argc, char *const argv[], char *const *const envp)
> .handled_access_fs = access_fs_rw,
> .handled_access_net = LANDLOCK_ACCESS_NET_BIND_TCP |
> LANDLOCK_ACCESS_NET_CONNECT_TCP,
> + .scoped = LANDLOCK_SCOPED_ABSTRACT_UNIX_SOCKET,
> };
>
> if (argc < 2) {
> fprintf(stderr,
> - "usage: %s=\"...\" %s=\"...\" %s=\"...\" %s=\"...\"%s "
> + "usage: %s=\"...\" %s=\"...\" %s=\"...\" %s=\"...\" %s=\"...\" %s "
> "<cmd> [args]...\n\n",
> ENV_FS_RO_NAME, ENV_FS_RW_NAME, ENV_TCP_BIND_NAME,
> - ENV_TCP_CONNECT_NAME, argv[0]);
> + ENV_TCP_CONNECT_NAME, ENV_SCOPED_NAME, argv[0]);
> fprintf(stderr,
> "Execute a command in a restricted environment.\n\n");
> fprintf(stderr,
> @@ -251,15 +289,18 @@ int main(const int argc, char *const argv[], char *const *const envp)
> fprintf(stderr,
> "* %s: list of ports allowed to connect (client).\n",
> ENV_TCP_CONNECT_NAME);
> + fprintf(stderr, "* %s: list of restrictions on IPCs.\n",
> + ENV_SCOPED_NAME);
> fprintf(stderr,
> "\nexample:\n"
> "%s=\"${PATH}:/lib:/usr:/proc:/etc:/dev/urandom\" "
> "%s=\"/dev/null:/dev/full:/dev/zero:/dev/pts:/tmp\" "
> "%s=\"9418\" "
> "%s=\"80:443\" "
> + "%s=\"a\" "
> "%s bash -i\n\n",
> ENV_FS_RO_NAME, ENV_FS_RW_NAME, ENV_TCP_BIND_NAME,
> - ENV_TCP_CONNECT_NAME, argv[0]);
> + ENV_TCP_CONNECT_NAME, ENV_SCOPED_NAME, argv[0]);
> fprintf(stderr,
> "This sandboxer can use Landlock features "
> "up to ABI version %d.\n",
> @@ -327,6 +368,10 @@ int main(const int argc, char *const argv[], char *const *const envp)
> /* Removes LANDLOCK_ACCESS_FS_IOCTL_DEV for ABI < 5 */
> ruleset_attr.handled_access_fs &= ~LANDLOCK_ACCESS_FS_IOCTL_DEV;
>
> + __attribute__((fallthrough));
> + case 5:
> + /* Removes LANDLOCK_SCOPED_ABSTRACT_UNIX_SOCKET for ABI < 6 */
> + ruleset_attr.scoped &= ~LANDLOCK_SCOPED_ABSTRACT_UNIX_SOCKET;
> fprintf(stderr,
> "Hint: You should update the running kernel "
> "to leverage Landlock features "
> @@ -358,6 +403,9 @@ int main(const int argc, char *const argv[], char *const *const envp)
> ~LANDLOCK_ACCESS_NET_CONNECT_TCP;
> }
>
> + if (abi >= 6 && !check_ruleset_scope(ENV_SCOPED_NAME, &ruleset_attr))
Instead of explicitly re-checking the ABI, check_ruleset_scope() should
check ruleset_attr.scoped & LANDLOCK_SCOPED_ABSTRACT_UNIX_SOCKET
> + return 1;
> +
> ruleset_fd =
> landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0);
> if (ruleset_fd < 0) {
> --
> 2.34.1
>
>
next prev parent reply other threads:[~2024-08-21 15:59 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-08-20 4:08 [PATCH v10 0/6] Landlock: Add abstract UNIX socket connect restriction Tahera Fahimi
2024-08-20 4:08 ` [PATCH v10 1/6] " Tahera Fahimi
2024-08-20 19:14 ` Simon Horman
2024-08-20 4:08 ` [PATCH v10 2/6] selftests/Landlock: general scoped restriction tests Tahera Fahimi
2024-08-20 15:58 ` Mickaël Salaün
2024-08-20 4:08 ` [PATCH v10 3/6] selftests/Landlock: Abstract UNIX socket " Tahera Fahimi
2024-08-20 16:00 ` Mickaël Salaün
2024-08-20 4:08 ` [PATCH v10 4/6] selftests/Landlock: Add pathname UNIX socket tests Tahera Fahimi
2024-08-20 4:08 ` [PATCH v10 5/6] sample/Landlock: Support abstract unix socket restriction Tahera Fahimi
2024-08-21 15:59 ` Mickaël Salaün [this message]
2024-08-20 4:08 ` [PATCH v10 6/6] Landlock: Document LANDLOCK_SCOPED_ABSTRACT_UNIX_SOCKET and ABI versioning Tahera Fahimi
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=20240821.Ohph8see3ru2@digikod.net \
--to=mic@digikod.net \
--cc=bjorn3_gh@protonmail.com \
--cc=fahimitahera@gmail.com \
--cc=gnoack@google.com \
--cc=jannh@google.com \
--cc=jmorris@namei.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-security-module@vger.kernel.org \
--cc=netdev@vger.kernel.org \
--cc=outreachy@lists.linux.dev \
--cc=paul@paul-moore.com \
--cc=serge@hallyn.com \
/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.