[PATCH v2 1/2] mm/memfd_luo: carry the sealed exec-bit state in the preserved record

Haolong Wang 18766350203 at 163.com
Tue Oct 13 20:52:16 PDT 2026


Thanks, this is valid, and it covers the pre-existing bit as well.

SysV SHM is created through shmem_kernel_file_setup(), which is the wrapper
that passes S_PRIVATE down to __shmem_file_setup():

    shmem_kernel_file_setup() -> __shmem_file_setup(..., S_PRIVATE)
    shmem_file_setup()        -> __shmem_file_setup(..., 0)

Both end in clear_nlink(), so the inode is unlinked either way and the
existing predicate

    return shmem_file(file) && !inode->i_nlink;

admits the segment.  A descriptor obtained through /proc/<pid>/map_files/
refers to the same inode, so it reaches the preserve ioctl, and the flags
word it then shares is the one SHMEM_F_LOCKED lives in: shmem_lock() states
it itself ("What serializes the accesses to info->flags?  ipc_lock_object()
when called from shmctl_do_lock()"), while the LUO side holds the inode
lock.  That mismatch is older than this series -- SHMEM_F_MAPPING_FROZEN
was already updated the same way, so the new seal-state freeze only adds
another bit to it.

I will add a preparatory patch that rejects kernel-private shmem inodes
from the memfd LUO handler:

    return shmem_file(file) && !IS_PRIVATE(inode) && !inode->i_nlink;

Real memfds come from shmem_file_setup() without S_PRIVATE, so memfd
support is untouched.  What the check removes is exactly the
shmem_kernel_file_setup() set: SysV SHM, big_key payloads, the XFS buffer
and scrub files, and the anonymous /dev/zero mapping file.  Because
SHMEM_F_LOCKED is only maintained for SysV segments, dropping those also
removes the handler's only concurrent writer of that word.  That is why
this does not need the flags word synchronized or the shmem_lock()
read-modify-writes turned into atomic bit operations: both sides would have
to change for that to help (one atomic side still loses against one plain
read-modify-write side), and it would be a patch for the shmem and ipc
maintainers rather than for this series.

One thing I am not claiming: this does not narrow the handler to
memfd_create() objects.  Unlinked non-private shmem files, a deleted tmpfs
file for example, keep being accepted; they are simply not part of this
race.

Measured on the same tree, with CONFIG_CHECKPOINT_RESTORE and CONFIG_SYSVIPC
enabled so that a segment descriptor is reachable, running the preserve
ioctl on the descriptor taken from /proc/self/map_files (memfd_luo is the
only file handler registered in that configuration):

  kernel                SysV SHM fd        memfd     unlinked tmpfs
  without the patch     accepted (0)       accepted  accepted
  with the patch        -ENOENT (errno 2)  accepted  accepted

The sysv descriptor reads back as "/SYSV00000000 (deleted)"; the two other
objects are the controls that show the ioctl path still works and that the
check is limited to kernel-private files.

v3 will follow as a separate thread: the new patch first, then the two
patches of v2 unchanged.




More information about the kexec mailing list