[PATCH v7 3/6] mm/memfd: add MFD_NOEXEC_SEAL and MFD_EXEC
SeongJae Park
sj at kernel.org
Fri Dec 16 18:39:49 UTC 2022
Hi Jeff,
> From: Jeff Xu <jeffxu at google.com>
>
> The new MFD_NOEXEC_SEAL and MFD_EXEC flags allows application to
> set executable bit at creation time (memfd_create).
>
> When MFD_NOEXEC_SEAL is set, memfd is created without executable bit
> (mode:0666), and sealed with F_SEAL_EXEC, so it can't be chmod to
> be executable (mode: 0777) after creation.
>
> when MFD_EXEC flag is set, memfd is created with executable bit
> (mode:0777), this is the same as the old behavior of memfd_create.
>
> The new pid namespaced sysctl vm.memfd_noexec has 3 values:
> 0: memfd_create() without MFD_EXEC nor MFD_NOEXEC_SEAL acts like
> MFD_EXEC was set.
> 1: memfd_create() without MFD_EXEC nor MFD_NOEXEC_SEAL acts like
> MFD_NOEXEC_SEAL was set.
> 2: memfd_create() without MFD_NOEXEC_SEAL will be rejected.
>
> The sysctl allows finer control of memfd_create for old-software
> that doesn't set the executable bit, for example, a container with
> vm.memfd_noexec=1 means the old-software will create non-executable
> memfd by default. Also, the value of memfd_noexec is passed to child
> namespace at creation time. For example, if the init namespace has
> vm.memfd_noexec=2, all its children namespaces will be created with 2.
>
> Signed-off-by: Jeff Xu <jeffxu at google.com>
> Co-developed-by: Daniel Verkamp <dverkamp at chromium.org>
> Signed-off-by: Daniel Verkamp <dverkamp at chromium.org>
> Reported-by: kernel test robot <lkp at intel.com>
> ---
[...]
> diff --git a/kernel/pid_namespace.c b/kernel/pid_namespace.c
> index f4f8cb0435b4..8a98b1af9376 100644
> --- a/kernel/pid_namespace.c
> +++ b/kernel/pid_namespace.c
> @@ -23,6 +23,7 @@
> #include <linux/sched/task.h>
> #include <linux/sched/signal.h>
> #include <linux/idr.h>
> +#include "pid_sysctl.h"
>
> static DEFINE_MUTEX(pid_caches_mutex);
> static struct kmem_cache *pid_ns_cachep;
> @@ -110,6 +111,8 @@ static struct pid_namespace *create_pid_namespace(struct user_namespace *user_ns
> ns->ucounts = ucounts;
> ns->pid_allocated = PIDNS_ADDING;
>
> + initialize_memfd_noexec_scope(ns);
> +
> return ns;
>
> out_free_idr:
> @@ -455,6 +458,8 @@ static __init int pid_namespaces_init(void)
> #ifdef CONFIG_CHECKPOINT_RESTORE
> register_sysctl_paths(kern_path, pid_ns_ctl_table);
> #endif
> +
> + register_pid_ns_sysctl_table_vm();
> return 0;
> }
[...]
>
> diff --git a/kernel/pid_sysctl.h b/kernel/pid_sysctl.h
> new file mode 100644
> index 000000000000..90a93161a122
> --- /dev/null
> +++ b/kernel/pid_sysctl.h
> @@ -0,0 +1,59 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +#ifndef LINUX_PID_SYSCTL_H
> +#define LINUX_PID_SYSCTL_H
> +
> +#include <linux/pid_namespace.h>
> +
> +#if defined(CONFIG_SYSCTL) && defined(CONFIG_MEMFD_CREATE)
> +static inline void initialize_memfd_noexec_scope(struct pid_namespace *ns)
[...]
> +static inline void register_pid_ns_sysctl_table_vm(void)
> +{
> + register_sysctl_paths(vm_path, pid_ns_ctl_table_vm);
> +}
> +#else
> +static inline void set_memfd_noexec_scope(struct pid_namespace *ns) {}
> +static inline void register_pid_ns_ctl_table_vm(void) {}
> +#endif
[...]
I found this patch makes build fails whne CONFIG_SYSCTL or CONFIG_MEMFD_CREATE
are not defined, as initialize_memfd_noexec_scope() and
register_pid_ns_sysctl_table_vm() are used from pid_namespace.c without the
configs protection.
I just posted a patch for that:
https://lore.kernel.org/linux-mm/20221216183314.169707-1-sj@kernel.org/
Could you please check?
Thanks,
SJ
More information about the Linux-security-module-archive
mailing list