lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20250817075252.4137628-1-safinaskar@zohomail.com>
Date: Sun, 17 Aug 2025 10:52:52 +0300
From: Askar Safin <safinaskar@...omail.com>
To: cyphar@...har.com
Cc: alx@...nel.org,
	brauner@...nel.org,
	dhowells@...hat.com,
	g.branden.robinson@...il.com,
	jack@...e.cz,
	linux-api@...r.kernel.org,
	linux-fsdevel@...r.kernel.org,
	linux-kernel@...r.kernel.org,
	linux-man@...r.kernel.org,
	mtk.manpages@...il.com,
	safinaskar@...omail.com,
	viro@...iv.linux.org.uk,
	Ian Kent <raven@...maw.net>,
	autofs mailing list <autofs@...r.kernel.org>
Subject: Re: [PATCH v3 00/12] man2: document "new" mount API

I noticed that you changed docs for automounts.
So I dig into automounts implementation.
And I found a bug in openat2.
If RESOLVE_NO_XDEV is specified, then name resolution
doesn't cross automount points (i. e. we get EXDEV),
but automounts still happen!
I think this is a bug.
Bug is reproduced in 6.17-rc1.
In the end of this mail you will find reproducer.
And miniconfig.

If you send patches for this bug, please, CC me.

Are automounts actually used? Is it possible to deprecate or
remove them? It seems for me automounts are rarely tested obscure
feature, which affects core namei code.

This reproducer is based on "tracing" automount, which
actually *IS* already deprecated. But automount mechanism
itself is not deprecated, as well as I know.

Also, I did read namei code, and I think that
options AT_NO_AUTOMOUNT, FSPICK_NO_AUTOMOUNT, etc affect
last component only, not all of them. I didn't test this yet.
I plan to test this within next days.

Also, I still didn't finish my experiments. Hopefully I will
finish them in 7 days. :)

Askar Safin

====

miniconfig:

CONFIG_64BIT=y

CONFIG_EXPERT=y

CONFIG_PRINTK=y
CONFIG_PRINTK_TIME=y

CONFIG_TTY=y
CONFIG_VT=y
CONFIG_VT_CONSOLE=y
CONFIG_FRAMEBUFFER_CONSOLE=y

CONFIG_PROC_FS=y
CONFIG_DEVTMPFS=y
CONFIG_SYSFS=y
CONFIG_TMPFS=y
CONFIG_DEBUG_FS=y
CONFIG_USER_EVENTS=y
CONFIG_FTRACE=y
CONFIG_MULTIUSER=y
CONFIG_NAMESPACES=y
CONFIG_USER_NS=y
CONFIG_PID_NS=y


CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y

CONFIG_BLK_DEV_INITRD=y
CONFIG_RD_GZIP=y

CONFIG_BINFMT_ELF=y
CONFIG_BINFMT_SCRIPT=y

CONFIG_TRACEFS_AUTOMOUNT_DEPRECATED=y

CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y

====

/*
Author: Askar Safin
Public domain

Make sure your kernel is compiled with CONFIG_TRACEFS_AUTOMOUNT_DEPRECATED=y

If that openat2 bug reproduces, then this program will
print "BUG REPRODUCED". If openat2 is fixed, then
the program will print "BUG NOT REPRODUCED".
Any other output means that something gone wrong,
i. e. results are indeterminate.

This program requires root in initial user namespace
*/

#define _GNU_SOURCE
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sched.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/mount.h>
#include <sys/syscall.h>
#include <linux/openat2.h>

int
main (void)
{
    if (unshare (CLONE_NEWNS) != 0)
        {
            perror ("unshare");
            return 1;
        }
    if (mount (NULL, "/", NULL, MS_REC | MS_PRIVATE, NULL) != 0)
        {
            perror ("mount(NULL, /, NULL, MS_REC | MS_PRIVATE, NULL)");
            return 1;
        }
    if (mount (NULL, "/tmp", "tmpfs", 0, NULL) != 0)
        {
            perror ("mount tmpfs");
            return 1;
        }
    if (mkdir ("/tmp/debugfs", 0777) != 0)
        {
            perror ("mkdir(/tmp/debugfs)");
            return 1;
        }
    if (mount (NULL, "/tmp/debugfs", "debugfs", 0, NULL) != 0)
        {
            perror ("mount debugfs");
            return 1;
        }
    {
        struct statx tracing;
        if (statx (AT_FDCWD, "/tmp/debugfs/tracing", AT_NO_AUTOMOUNT, 0, &tracing) != 0)
            {
                perror ("statx tracing");
                return 1;
            }
        if (!(tracing.stx_attributes_mask & STATX_ATTR_MOUNT_ROOT))
            {
                fprintf (stderr, "???\n");
                return 1;
            }
        // Let's check that nothing is mounted at /tmp/debugfs/tracing yet
        if (tracing.stx_attributes & STATX_ATTR_MOUNT_ROOT)
            {
                fprintf (stderr, "Something already mounted at /tmp/debugfs/tracing\n");
                return 1;
            }
    }
    if (chdir ("/tmp/debugfs") != 0)
        {
            perror ("chdir");
            return 1;
        }
    {
        struct open_how how;
        memset (&how, 0, sizeof how);
        how.flags = O_DIRECTORY;
        how.mode = 0;
        how.resolve = RESOLVE_NO_XDEV | RESOLVE_NO_MAGICLINKS | RESOLVE_NO_SYMLINKS;
        if (syscall (SYS_openat2, AT_FDCWD, "tracing", &how, sizeof how) != -1)
            {
                fprintf (stderr, "openat2 crossed automount point");
                return 1;
            }
        if (errno != EXDEV)
            {
                fprintf (stderr, "wrong errno");
                return 1;
            }
    }
    {
        struct statx tracing;
        if (statx (AT_FDCWD, "/tmp/debugfs/tracing", AT_NO_AUTOMOUNT, 0, &tracing) != 0)
            {
                perror ("statx tracing (2)");
                return 1;
            }
        if (!(tracing.stx_attributes_mask & STATX_ATTR_MOUNT_ROOT))
            {
                fprintf (stderr, "???\n");
                return 1;
            }
        if (tracing.stx_attributes & STATX_ATTR_MOUNT_ROOT)
            {
                fprintf (stderr, "BUG REPRODUCED. Something mounted at /tmp/debugfs/tracing\n");
                return 0;
            }
        else
            {
                fprintf (stderr, "BUG NOT REPRODUCED\n");
                return 0;
            }
    }
}

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ