Skip to content

Commit 1e7ab6f

Browse files
committed
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/[email protected] Fixes: cfd86ef ("anon_inode: use a proper mode internally") Acked-by: Jens Axboe <[email protected]> Cc: [email protected] Reported-by: Jens Axboe <[email protected]> Signed-off-by: Christian Brauner <[email protected]>
1 parent d5cb81b commit 1e7ab6f

File tree

3 files changed

+11
-8
lines changed

3 files changed

+11
-8
lines changed

fs/exec.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,9 @@ static inline void put_binfmt(struct linux_binfmt * fmt)
114114

115115
bool path_noexec(const struct path *path)
116116
{
117+
/* If it's an anonymous inode make sure that we catch any shenanigans. */
118+
VFS_WARN_ON_ONCE(IS_ANON_FILE(d_inode(path->dentry)) &&
119+
!(path->mnt->mnt_sb->s_iflags & SB_I_NOEXEC));
117120
return (path->mnt->mnt_flags & MNT_NOEXEC) ||
118121
(path->mnt->mnt_sb->s_iflags & SB_I_NOEXEC);
119122
}
@@ -781,13 +784,15 @@ static struct file *do_open_execat(int fd, struct filename *name, int flags)
781784
if (IS_ERR(file))
782785
return file;
783786

787+
if (path_noexec(&file->f_path))
788+
return ERR_PTR(-EACCES);
789+
784790
/*
785791
* In the past the regular type check was here. It moved to may_open() in
786792
* 633fb6ac3980 ("exec: move S_ISREG() check earlier"). Since then it is
787793
* an invariant that all non-regular files error out before we get here.
788794
*/
789-
if (WARN_ON_ONCE(!S_ISREG(file_inode(file)->i_mode)) ||
790-
path_noexec(&file->f_path))
795+
if (WARN_ON_ONCE(!S_ISREG(file_inode(file)->i_mode)))
791796
return ERR_PTR(-EACCES);
792797

793798
err = exe_file_deny_write_access(file);

fs/libfs.c

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1649,12 +1649,10 @@ struct inode *alloc_anon_inode(struct super_block *s)
16491649
*/
16501650
inode->i_state = I_DIRTY;
16511651
/*
1652-
* Historically anonymous inodes didn't have a type at all and
1653-
* userspace has come to rely on this. Internally they're just
1654-
* regular files but S_IFREG is masked off when reporting
1655-
* information to userspace.
1652+
* Historically anonymous inodes don't have a type at all and
1653+
* userspace has come to rely on this.
16561654
*/
1657-
inode->i_mode = S_IFREG | S_IRUSR | S_IWUSR;
1655+
inode->i_mode = S_IRUSR | S_IWUSR;
16581656
inode->i_uid = current_fsuid();
16591657
inode->i_gid = current_fsgid();
16601658
inode->i_flags |= S_PRIVATE | S_ANON_INODE;

fs/namei.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3471,7 +3471,7 @@ static int may_open(struct mnt_idmap *idmap, const struct path *path,
34713471
return -EACCES;
34723472
break;
34733473
default:
3474-
VFS_BUG_ON_INODE(1, inode);
3474+
VFS_BUG_ON_INODE(!IS_ANON_FILE(inode), inode);
34753475
}
34763476

34773477
error = inode_permission(idmap, inode, MAY_OPEN | acc_mode);

0 commit comments

Comments
 (0)