mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	anon_inode: rework assertions
Making anonymous inodes regular files comes with a lot of risk and
regression potential as evidenced by a recent hickup in io_uring. We're
better of continuing to not have them be regular files. Since we have
S_ANON_INODE we can port all of our assertions easily.
Link: https://lore.kernel.org/20250702-work-fixes-v1-1-ff76ea589e33@kernel.org
Fixes: cfd86ef7e8 ("anon_inode: use a proper mode internally")
Acked-by: Jens Axboe <axboe@kernel.dk>
Cc: stable@kernel.org
Reported-by: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Christian Brauner <brauner@kernel.org>
			
			
This commit is contained in:
		
							parent
							
								
									d5cb81ba92
								
							
						
					
					
						commit
						1e7ab6f678
					
				
					 3 changed files with 11 additions and 8 deletions
				
			
		| 
						 | 
					@ -114,6 +114,9 @@ static inline void put_binfmt(struct linux_binfmt * fmt)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool path_noexec(const struct path *path)
 | 
					bool path_noexec(const struct path *path)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						/* If it's an anonymous inode make sure that we catch any shenanigans. */
 | 
				
			||||||
 | 
						VFS_WARN_ON_ONCE(IS_ANON_FILE(d_inode(path->dentry)) &&
 | 
				
			||||||
 | 
								 !(path->mnt->mnt_sb->s_iflags & SB_I_NOEXEC));
 | 
				
			||||||
	return (path->mnt->mnt_flags & MNT_NOEXEC) ||
 | 
						return (path->mnt->mnt_flags & MNT_NOEXEC) ||
 | 
				
			||||||
	       (path->mnt->mnt_sb->s_iflags & SB_I_NOEXEC);
 | 
						       (path->mnt->mnt_sb->s_iflags & SB_I_NOEXEC);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -781,13 +784,15 @@ static struct file *do_open_execat(int fd, struct filename *name, int flags)
 | 
				
			||||||
	if (IS_ERR(file))
 | 
						if (IS_ERR(file))
 | 
				
			||||||
		return file;
 | 
							return file;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (path_noexec(&file->f_path))
 | 
				
			||||||
 | 
							return ERR_PTR(-EACCES);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
	 * In the past the regular type check was here. It moved to may_open() in
 | 
						 * In the past the regular type check was here. It moved to may_open() in
 | 
				
			||||||
	 * 633fb6ac3980 ("exec: move S_ISREG() check earlier"). Since then it is
 | 
						 * 633fb6ac3980 ("exec: move S_ISREG() check earlier"). Since then it is
 | 
				
			||||||
	 * an invariant that all non-regular files error out before we get here.
 | 
						 * an invariant that all non-regular files error out before we get here.
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	if (WARN_ON_ONCE(!S_ISREG(file_inode(file)->i_mode)) ||
 | 
						if (WARN_ON_ONCE(!S_ISREG(file_inode(file)->i_mode)))
 | 
				
			||||||
	    path_noexec(&file->f_path))
 | 
					 | 
				
			||||||
		return ERR_PTR(-EACCES);
 | 
							return ERR_PTR(-EACCES);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	err = exe_file_deny_write_access(file);
 | 
						err = exe_file_deny_write_access(file);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1649,12 +1649,10 @@ struct inode *alloc_anon_inode(struct super_block *s)
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	inode->i_state = I_DIRTY;
 | 
						inode->i_state = I_DIRTY;
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
	 * Historically anonymous inodes didn't have a type at all and
 | 
						 * Historically anonymous inodes don't have a type at all and
 | 
				
			||||||
	 * userspace has come to rely on this. Internally they're just
 | 
						 * userspace has come to rely on this.
 | 
				
			||||||
	 * regular files but S_IFREG is masked off when reporting
 | 
					 | 
				
			||||||
	 * information to userspace.
 | 
					 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	inode->i_mode = S_IFREG | S_IRUSR | S_IWUSR;
 | 
						inode->i_mode = S_IRUSR | S_IWUSR;
 | 
				
			||||||
	inode->i_uid = current_fsuid();
 | 
						inode->i_uid = current_fsuid();
 | 
				
			||||||
	inode->i_gid = current_fsgid();
 | 
						inode->i_gid = current_fsgid();
 | 
				
			||||||
	inode->i_flags |= S_PRIVATE | S_ANON_INODE;
 | 
						inode->i_flags |= S_PRIVATE | S_ANON_INODE;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3471,7 +3471,7 @@ static int may_open(struct mnt_idmap *idmap, const struct path *path,
 | 
				
			||||||
			return -EACCES;
 | 
								return -EACCES;
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
		VFS_BUG_ON_INODE(1, inode);
 | 
							VFS_BUG_ON_INODE(!IS_ANON_FILE(inode), inode);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	error = inode_permission(idmap, inode, MAY_OPEN | acc_mode);
 | 
						error = inode_permission(idmap, inode, MAY_OPEN | acc_mode);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue