Commit bd9b51e79cb0b8bc00a7e0076a4a8963ca4a797c

Authored by Al Viro
1 parent 1f55a6ec94

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

arch/ia64/kernel/perfmon.c
... ... @@ -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);
... ... @@ -5,8 +5,6 @@
5 5 # Rewritten to use lists instead of if-statements.
6 6 #
7 7  
8   -obj-y := nonet.o
9   -
10 8 obj-$(CONFIG_NET) := socket.o core/
11 9  
12 10 tmp-$(CONFIG_COMPAT) := compat.o
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