mirror of
https://gitee.com/bianbu-linux/linux-6.6
synced 2025-07-01 23:53:16 -04:00
make default ->i_fop have ->open() fail with ENXIO
As it is, default ->i_fop has NULL ->open() (along with all other methods). The only case where it matters is reopening (via procfs symlink) a file that didn't get its ->f_op from ->i_fop - anything else will have ->i_fop assigned to something sane (default would fail on read/write/ioctl/etc.). Unfortunately, such case exists - alloc_file() users, especially anon_get_file() ones. There we have tons of opened files of very different kinds sharing the same inode. As the result, attempt to reopen those via procfs succeeds and you get a descriptor you can't do anything with. Moreover, in case of sockets we set ->i_fop that will only be used on such reopen attempts - and put a failing ->open() into it to make sure those do not succeed. It would be simpler to put such ->open() into default ->i_fop and leave it unchanged both for anon inode (as we do anyway) and for socket ones. Result: * everything going through do_dentry_open() works as it used to * sock_no_open() kludge is gone * attempts to reopen anon-inode files fail as they really ought to * ditto for aio_private_file() * ditto for perfmon - this one actually tried to imitate sock_no_open() trick, but failed to set ->i_fop, so in the current tree reopens succeed and yield completely useless descriptor. Intent clearly had been to fail with -ENXIO on such reopens; now it actually does. * everything else that used alloc_file() keeps working - it has ->i_fop set for its inodes anyway Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
parent
1f55a6ec94
commit
bd9b51e79c
6 changed files with 8 additions and 61 deletions
11
fs/inode.c
11
fs/inode.c
|
@ -114,6 +114,11 @@ int proc_nr_inodes(struct ctl_table *table, int write,
|
|||
}
|
||||
#endif
|
||||
|
||||
static int no_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
/**
|
||||
* inode_init_always - perform inode structure intialisation
|
||||
* @sb: superblock inode belongs to
|
||||
|
@ -125,7 +130,7 @@ int proc_nr_inodes(struct ctl_table *table, int write,
|
|||
int inode_init_always(struct super_block *sb, struct inode *inode)
|
||||
{
|
||||
static const struct inode_operations empty_iops;
|
||||
static const struct file_operations empty_fops;
|
||||
static const struct file_operations no_open_fops = {.open = no_open};
|
||||
struct address_space *const mapping = &inode->i_data;
|
||||
|
||||
inode->i_sb = sb;
|
||||
|
@ -133,7 +138,7 @@ int inode_init_always(struct super_block *sb, struct inode *inode)
|
|||
inode->i_flags = 0;
|
||||
atomic_set(&inode->i_count, 1);
|
||||
inode->i_op = &empty_iops;
|
||||
inode->i_fop = &empty_fops;
|
||||
inode->i_fop = &no_open_fops;
|
||||
inode->__i_nlink = 1;
|
||||
inode->i_opflags = 0;
|
||||
i_uid_write(inode, 0);
|
||||
|
@ -1801,7 +1806,7 @@ void init_special_inode(struct inode *inode, umode_t mode, dev_t rdev)
|
|||
} else if (S_ISFIFO(mode))
|
||||
inode->i_fop = &pipefifo_fops;
|
||||
else if (S_ISSOCK(mode))
|
||||
inode->i_fop = &bad_sock_fops;
|
||||
; /* leave it no_open_fops */
|
||||
else
|
||||
printk(KERN_DEBUG "init_special_inode: bogus i_mode (%o) for"
|
||||
" inode %s:%lu\n", mode, inode->i_sb->s_id,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue