On Wed, Apr 02, 2025 at 06:59:46PM -0700, Penglei Jiang wrote: > may_open() > { > ... > switch (inode->i_mode & S_IFMT) { > case S_IFLNK: > case S_IFDIR: > case S_IFBLK: > case S_IFCHR: > case S_IFIFO: > case S_IFSOCK: > case S_IFREG: > default: > VFS_BUG_ON_INODE(1, inode); > } > ... > } > > Since some anonymous inodes do not have S_IFLNK, S_IFDIR, S_IFBLK, > S_IFCHR, S_IFIFO, S_IFSOCK, or S_IFREG flags set when created, they > end up in the default case branch. > > When creating some anon_inode instances, the i_mode in the switch > statement is not properly set, which causes the open operation to > follow the default branch when opening anon_inode. > > We could check whether the inode is an anon_inode before VFS_BUG_ON_INODE > and trigger the assertion only if it's not. However, a more reasonable > approach might be to set a flag during creation in alloc_anon_inode(), > such as inode->i_flags |= S_ANON, to explicitly mark anonymous inodes. > I think this is the right step, but there is a missing bit. The assert was added because of a prior bug report involving ntfs, where a misconstructed inode did not have an i_mode and was passed to execve. That eventually landed in may_open() which did not check for MAY_EXEC as the inode did not fit any of the modes. It was only caught by a hardening check later. Note all other cases handle MAY_EXEC. So I think the safest way forward has 2 steps in the default case: - detect inodes which purposefully don't have a valid mode and elide the assert if so, for example like in your patch - add the permission check: if (acc_mode & MAY_EXEC) return -EACCES; The hardening check comes with a WARN_ON if the inode is not S_ISREG. No need to hope none of the anon inodes reach it, this should just be short-circuited.