Commit bd9b51e79cb0b8bc00a7e0076a4a8963ca4a797c
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>
Showing 6 changed files with 8 additions and 61 deletions Side-by-side Diff
... | ... | @@ -2145,22 +2145,12 @@ |
2145 | 2145 | return 0; |
2146 | 2146 | } |
2147 | 2147 | |
2148 | -static int | |
2149 | -pfm_no_open(struct inode *irrelevant, struct file *dontcare) | |
2150 | -{ | |
2151 | - DPRINT(("pfm_no_open called\n")); | |
2152 | - return -ENXIO; | |
2153 | -} | |
2154 | - | |
2155 | - | |
2156 | - | |
2157 | 2148 | static const struct file_operations pfm_file_ops = { |
2158 | 2149 | .llseek = no_llseek, |
2159 | 2150 | .read = pfm_read, |
2160 | 2151 | .write = pfm_write, |
2161 | 2152 | .poll = pfm_poll, |
2162 | 2153 | .unlocked_ioctl = pfm_ioctl, |
2163 | - .open = pfm_no_open, /* special open code to disallow open via /proc */ | |
2164 | 2154 | .fasync = pfm_fasync, |
2165 | 2155 | .release = pfm_close, |
2166 | 2156 | .flush = pfm_flush |
... | ... | @@ -114,6 +114,11 @@ |
114 | 114 | } |
115 | 115 | #endif |
116 | 116 | |
117 | +static int no_open(struct inode *inode, struct file *file) | |
118 | +{ | |
119 | + return -ENXIO; | |
120 | +} | |
121 | + | |
117 | 122 | /** |
118 | 123 | * inode_init_always - perform inode structure intialisation |
119 | 124 | * @sb: superblock inode belongs to |
... | ... | @@ -125,7 +130,7 @@ |
125 | 130 | int inode_init_always(struct super_block *sb, struct inode *inode) |
126 | 131 | { |
127 | 132 | static const struct inode_operations empty_iops; |
128 | - static const struct file_operations empty_fops; | |
133 | + static const struct file_operations no_open_fops = {.open = no_open}; | |
129 | 134 | struct address_space *const mapping = &inode->i_data; |
130 | 135 | |
131 | 136 | inode->i_sb = sb; |
... | ... | @@ -133,7 +138,7 @@ |
133 | 138 | inode->i_flags = 0; |
134 | 139 | atomic_set(&inode->i_count, 1); |
135 | 140 | inode->i_op = &empty_iops; |
136 | - inode->i_fop = &empty_fops; | |
141 | + inode->i_fop = &no_open_fops; | |
137 | 142 | inode->__i_nlink = 1; |
138 | 143 | inode->i_opflags = 0; |
139 | 144 | i_uid_write(inode, 0); |
... | ... | @@ -1801,7 +1806,7 @@ |
1801 | 1806 | } else if (S_ISFIFO(mode)) |
1802 | 1807 | inode->i_fop = &pipefifo_fops; |
1803 | 1808 | else if (S_ISSOCK(mode)) |
1804 | - inode->i_fop = &bad_sock_fops; | |
1809 | + ; /* leave it no_open_fops */ | |
1805 | 1810 | else |
1806 | 1811 | printk(KERN_DEBUG "init_special_inode: bogus i_mode (%o) for" |
1807 | 1812 | " inode %s:%lu\n", mode, inode->i_sb->s_id, |
... | ... | @@ -2151,7 +2151,6 @@ |
2151 | 2151 | extern int sync_filesystem(struct super_block *); |
2152 | 2152 | extern const struct file_operations def_blk_fops; |
2153 | 2153 | extern const struct file_operations def_chr_fops; |
2154 | -extern const struct file_operations bad_sock_fops; | |
2155 | 2154 | #ifdef CONFIG_BLOCK |
2156 | 2155 | extern int ioctl_by_bdev(struct block_device *, unsigned, unsigned long); |
2157 | 2156 | extern int blkdev_ioctl(struct block_device *, fmode_t, unsigned, unsigned long); |
1 | -/* | |
2 | - * net/nonet.c | |
3 | - * | |
4 | - * Dummy functions to allow us to configure network support entirely | |
5 | - * out of the kernel. | |
6 | - * | |
7 | - * Distributed under the terms of the GNU GPL version 2. | |
8 | - * Copyright (c) Matthew Wilcox 2003 | |
9 | - */ | |
10 | - | |
11 | -#include <linux/module.h> | |
12 | -#include <linux/errno.h> | |
13 | -#include <linux/fs.h> | |
14 | -#include <linux/init.h> | |
15 | -#include <linux/kernel.h> | |
16 | - | |
17 | -static int sock_no_open(struct inode *irrelevant, struct file *dontcare) | |
18 | -{ | |
19 | - return -ENXIO; | |
20 | -} | |
21 | - | |
22 | -const struct file_operations bad_sock_fops = { | |
23 | - .owner = THIS_MODULE, | |
24 | - .open = sock_no_open, | |
25 | - .llseek = noop_llseek, | |
26 | -}; |
... | ... | @@ -113,7 +113,6 @@ |
113 | 113 | unsigned int sysctl_net_busy_poll __read_mostly; |
114 | 114 | #endif |
115 | 115 | |
116 | -static int sock_no_open(struct inode *irrelevant, struct file *dontcare); | |
117 | 116 | static ssize_t sock_aio_read(struct kiocb *iocb, const struct iovec *iov, |
118 | 117 | unsigned long nr_segs, loff_t pos); |
119 | 118 | static ssize_t sock_aio_write(struct kiocb *iocb, const struct iovec *iov, |
... | ... | @@ -151,7 +150,6 @@ |
151 | 150 | .compat_ioctl = compat_sock_ioctl, |
152 | 151 | #endif |
153 | 152 | .mmap = sock_mmap, |
154 | - .open = sock_no_open, /* special open code to disallow open via /proc */ | |
155 | 153 | .release = sock_close, |
156 | 154 | .fasync = sock_fasync, |
157 | 155 | .sendpage = sock_sendpage, |
... | ... | @@ -558,23 +556,6 @@ |
558 | 556 | this_cpu_add(sockets_in_use, 1); |
559 | 557 | return sock; |
560 | 558 | } |
561 | - | |
562 | -/* | |
563 | - * In theory you can't get an open on this inode, but /proc provides | |
564 | - * a back door. Remember to keep it shut otherwise you'll let the | |
565 | - * creepy crawlies in. | |
566 | - */ | |
567 | - | |
568 | -static int sock_no_open(struct inode *irrelevant, struct file *dontcare) | |
569 | -{ | |
570 | - return -ENXIO; | |
571 | -} | |
572 | - | |
573 | -const struct file_operations bad_sock_fops = { | |
574 | - .owner = THIS_MODULE, | |
575 | - .open = sock_no_open, | |
576 | - .llseek = noop_llseek, | |
577 | -}; | |
578 | 559 | |
579 | 560 | /** |
580 | 561 | * sock_release - close a socket |
-
mentioned in commit e3bb50
-
mentioned in commit e3bb50
-
mentioned in commit ecb5ec
-
mentioned in commit ecb5ec
-
mentioned in commit e3bb50
-
mentioned in commit ecb5ec
-
mentioned in commit e3bb50
-
mentioned in commit ecb5ec
-
mentioned in commit e3bb50
-
mentioned in commit ecb5ec
-
mentioned in commit e3bb50
-
mentioned in commit ecb5ec
-
mentioned in commit e3bb50
-
mentioned in commit ecb5ec
-
mentioned in commit e3bb50
-
mentioned in commit ecb5ec
-
mentioned in commit e3bb50
-
mentioned in commit ecb5ec
-
mentioned in commit e3bb50
-
mentioned in commit ecb5ec
-
mentioned in commit e3bb50
-
mentioned in commit ecb5ec
-
mentioned in commit e3bb50
-
mentioned in commit ecb5ec
-
mentioned in commit e3bb50
-
mentioned in commit ecb5ec