Re: [PATCH] Fix regression due to "fs: move binfmt_misc sysctl to its own file"

From: Luis Chamberlain
Date: Mon Feb 07 2022 - 16:47:39 EST


On Mon, Feb 07, 2022 at 02:27:28PM +0100, Domenico Andreoli wrote:
> Commit 3ba442d5331f did not go unnoticed, binfmt-support stopped to
> work on my Debian system since v5.17-rc2 (did not check with -rc1).
>
> The existance of /proc/sys/fs/binfmt_misc is a precondition for
> attempting to mount the binfmt_misc fs, which in turn triggers the
> autoload of the binfmt_misc module. Without it, no module is loaded
> and no binfmt is available at boot.
>
> Building as built-in or manually loading the module and mounting the fs
> works fine, it's therefore only a matter of interaction with user-space.
>
> I could try to improve the Debian systemd configuration but I can't
> say anything about the other distributions.
>
> In the meanwhile this patch restores a working system right after boot.
>
> Fixes: 3ba442d5331f ("fs: move binfmt_misc sysctl to its own file")
> Signed-off-by: Domenico Andreoli <domenico.andreoli@xxxxxxxxx>
> Cc: Al Viro <viro@xxxxxxxxxxxxxxxxxx>
> Cc: Amir Goldstein <amir73il@xxxxxxxxx>
> Cc: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx>
> Cc: Andy Shevchenko <andriy.shevchenko@xxxxxxxxxxxxxxx>
> Cc: Antti Palosaari <crope@xxxxxx>
> Cc: Arnd Bergmann <arnd@xxxxxxxx>
> Cc: Benjamin Herrenschmidt <benh@xxxxxxxxxxxxxxxxxxx>
> Cc: Benjamin LaHaise <bcrl@xxxxxxxxx>
> Cc: Clemens Ladisch <clemens@xxxxxxxxxx>
> Cc: David Airlie <airlied@xxxxxxxx>
> Cc: Douglas Gilbert <dgilbert@xxxxxxxxxxxx>
> Cc: Eric Biederman <ebiederm@xxxxxxxxxxxx>
> Cc: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx>
> Cc: Iurii Zaikin <yzaikin@xxxxxxxxxx>
> Cc: James E.J. Bottomley <jejb@xxxxxxxxxxxxx>
> Cc: Jan Kara <jack@xxxxxxx>
> Cc: Jani Nikula <jani.nikula@xxxxxxxxx>
> Cc: Jani Nikula <jani.nikula@xxxxxxxxxxxxxxx>
> Cc: Joel Becker <jlbec@xxxxxxxxxxxx>
> Cc: John Ogness <john.ogness@xxxxxxxxxxxxx>
> Cc: Joonas Lahtinen <joonas.lahtinen@xxxxxxxxxxxxxxx>
> Cc: Joseph Qi <joseph.qi@xxxxxxxxxxxxxxxxx>
> Cc: Julia Lawall <julia.lawall@xxxxxxxx>
> Cc: Kees Cook <keescook@xxxxxxxxxxxx>
> Cc: Lukas Middendorf <kernel@xxxxxxxxxxx>
> Cc: Luis Chamberlain <mcgrof@xxxxxxxxxx>
> Cc: Mark Fasheh <mark@xxxxxxxxxx>
> Cc: Martin K. Petersen <martin.petersen@xxxxxxxxxx>
> Cc: Paul Turner <pjt@xxxxxxxxxx>
> Cc: Peter Zijlstra <peterz@xxxxxxxxxxxxx>
> Cc: Petr Mladek <pmladek@xxxxxxxx>
> Cc: Phillip Potter <phil@xxxxxxxxxxxxxxxx>
> Cc: Qing Wang <wangqing@xxxxxxxx>
> Cc: "Rafael J. Wysocki" <rafael@xxxxxxxxxx>
> Cc: Rodrigo Vivi <rodrigo.vivi@xxxxxxxxx>
> Cc: Sebastian Reichel <sre@xxxxxxxxxx>
> Cc: Sergey Senozhatsky <senozhatsky@xxxxxxxxxxxx>
> Cc: Stephen Kitt <steve@xxxxxxx>
> Cc: Steven Rostedt (VMware) <rostedt@xxxxxxxxxxx>
> Cc: Suren Baghdasaryan <surenb@xxxxxxxxxx>
> Cc: Tetsuo Handa <penguin-kernel@xxxxxxxxxxxxxxxxxxx>
> Cc: "Theodore Ts'o" <tytso@xxxxxxx>
> Cc: Xiaoming Ni <nixiaoming@xxxxxxxxxx>
>
> ---
> fs/binfmt_misc.c | 6 +-----
> kernel/sysctl.c | 13 +++++++++++++
> 2 files changed, 14 insertions(+), 5 deletions(-)
>
> Index: b/fs/binfmt_misc.c
> ===================================================================
> --- a/fs/binfmt_misc.c
> +++ b/fs/binfmt_misc.c
> @@ -817,20 +817,16 @@ static struct file_system_type bm_fs_typ
> };
> MODULE_ALIAS_FS("binfmt_misc");
>
> -static struct ctl_table_header *binfmt_misc_header;
> -
> static int __init init_misc_binfmt(void)
> {
> int err = register_filesystem(&bm_fs_type);
> if (!err)
> insert_binfmt(&misc_format);
> - binfmt_misc_header = register_sysctl_mount_point("fs/binfmt_misc");
> - return 0;
> + return err;
> }

OK I think the issue here should have been that declaring this on
fs/binfmt_misc.c creates the chicken and the egg issue, and so we
need to do this on built-in code. Instead of your patch can you try
this instead, it just always creates the sysctl mount always now
so long as proc sysctl is enabled. It does not do the unregistration
as we always want the path present as it used to be before as well.

diff --git a/fs/binfmt_misc.c b/fs/binfmt_misc.c
index c07f35719ee3..4b8f1b11a7c8 100644
--- a/fs/binfmt_misc.c
+++ b/fs/binfmt_misc.c
@@ -817,20 +817,16 @@ static struct file_system_type bm_fs_type = {
};
MODULE_ALIAS_FS("binfmt_misc");

-static struct ctl_table_header *binfmt_misc_header;
-
static int __init init_misc_binfmt(void)
{
int err = register_filesystem(&bm_fs_type);
if (!err)
insert_binfmt(&misc_format);
- binfmt_misc_header = register_sysctl_mount_point("fs/binfmt_misc");
return 0;
}

static void __exit exit_misc_binfmt(void)
{
- unregister_sysctl_table(binfmt_misc_header);
unregister_binfmt(&misc_format);
unregister_filesystem(&bm_fs_type);
}
diff --git a/fs/file_table.c b/fs/file_table.c
index 57edef16dce4..4f4739c9405c 100644
--- a/fs/file_table.c
+++ b/fs/file_table.c
@@ -119,6 +119,7 @@ static struct ctl_table fs_stat_sysctls[] = {
static int __init init_fs_stat_sysctls(void)
{
register_sysctl_init("fs", fs_stat_sysctls);
+ register_sysctl_mount_point("fs/binfmt_misc");
return 0;
}
fs_initcall(init_fs_stat_sysctls);