inode.c 11.8 KB
Newer Older
Linus Torvalds's avatar
Linus Torvalds committed
1 2 3 4 5 6 7 8 9
/*
 *  linux/fs/proc/inode.c
 *
 *  Copyright (C) 1991, 1992  Linus Torvalds
 */

#include <linux/time.h>
#include <linux/proc_fs.h>
#include <linux/kernel.h>
Vasiliy Kulikov's avatar
Vasiliy Kulikov committed
10
#include <linux/pid_namespace.h>
Linus Torvalds's avatar
Linus Torvalds committed
11 12 13
#include <linux/mm.h>
#include <linux/string.h>
#include <linux/stat.h>
14
#include <linux/completion.h>
15
#include <linux/poll.h>
Andrew Morton's avatar
Andrew Morton committed
16
#include <linux/printk.h>
Linus Torvalds's avatar
Linus Torvalds committed
17 18 19 20
#include <linux/file.h>
#include <linux/limits.h>
#include <linux/init.h>
#include <linux/module.h>
Al Viro's avatar
Al Viro committed
21
#include <linux/sysctl.h>
Vasiliy Kulikov's avatar
Vasiliy Kulikov committed
22
#include <linux/seq_file.h>
23
#include <linux/slab.h>
Vasiliy Kulikov's avatar
Vasiliy Kulikov committed
24
#include <linux/mount.h>
25
#include <linux/magic.h>
26
#include <linux/namei.h>
Linus Torvalds's avatar
Linus Torvalds committed
27 28 29

#include <asm/uaccess.h>

30
#include "internal.h"
Linus Torvalds's avatar
Linus Torvalds committed
31

Al Viro's avatar
Al Viro committed
32
static void proc_evict_inode(struct inode *inode)
Linus Torvalds's avatar
Linus Torvalds committed
33 34
{
	struct proc_dir_entry *de;
Al Viro's avatar
Al Viro committed
35
	struct ctl_table_header *head;
36
	const struct proc_ns_operations *ns_ops;
37
	void *ns;
Linus Torvalds's avatar
Linus Torvalds committed
38

39
	truncate_inode_pages(&inode->i_data, 0);
40
	clear_inode(inode);
41

42
	/* Stop tracking associated processes */
43
	put_pid(PROC_I(inode)->pid);
Linus Torvalds's avatar
Linus Torvalds committed
44 45 46

	/* Let go of any associated proc directory entry */
	de = PROC_I(inode)->pde;
47
	if (de)
48
		pde_put(de);
Al Viro's avatar
Al Viro committed
49 50 51 52 53
	head = PROC_I(inode)->sysctl;
	if (head) {
		rcu_assign_pointer(PROC_I(inode)->sysctl, NULL);
		sysctl_head_put(head);
	}
54
	/* Release any associated namespace */
55 56
	ns_ops = PROC_I(inode)->ns.ns_ops;
	ns = PROC_I(inode)->ns.ns;
57 58
	if (ns_ops && ns)
		ns_ops->put(ns);
Linus Torvalds's avatar
Linus Torvalds committed
59 60
}

61
static struct kmem_cache * proc_inode_cachep;
Linus Torvalds's avatar
Linus Torvalds committed
62 63 64 65 66 67

static struct inode *proc_alloc_inode(struct super_block *sb)
{
	struct proc_inode *ei;
	struct inode *inode;

68
	ei = (struct proc_inode *)kmem_cache_alloc(proc_inode_cachep, GFP_KERNEL);
Linus Torvalds's avatar
Linus Torvalds committed
69 70
	if (!ei)
		return NULL;
71
	ei->pid = NULL;
72
	ei->fd = 0;
Linus Torvalds's avatar
Linus Torvalds committed
73 74
	ei->op.proc_get_link = NULL;
	ei->pde = NULL;
Al Viro's avatar
Al Viro committed
75 76
	ei->sysctl = NULL;
	ei->sysctl_entry = NULL;
77 78
	ei->ns.ns = NULL;
	ei->ns.ns_ops = NULL;
Linus Torvalds's avatar
Linus Torvalds committed
79 80 81 82 83
	inode = &ei->vfs_inode;
	inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
	return inode;
}

Nick Piggin's avatar
Nick Piggin committed
84
static void proc_i_callback(struct rcu_head *head)
Linus Torvalds's avatar
Linus Torvalds committed
85
{
Nick Piggin's avatar
Nick Piggin committed
86
	struct inode *inode = container_of(head, struct inode, i_rcu);
Linus Torvalds's avatar
Linus Torvalds committed
87 88 89
	kmem_cache_free(proc_inode_cachep, PROC_I(inode));
}

Nick Piggin's avatar
Nick Piggin committed
90 91 92 93 94
static void proc_destroy_inode(struct inode *inode)
{
	call_rcu(&inode->i_rcu, proc_i_callback);
}

95
static void init_once(void *foo)
Linus Torvalds's avatar
Linus Torvalds committed
96 97 98
{
	struct proc_inode *ei = (struct proc_inode *) foo;

99
	inode_init_once(&ei->vfs_inode);
Linus Torvalds's avatar
Linus Torvalds committed
100
}
101

102
void __init proc_init_inodecache(void)
Linus Torvalds's avatar
Linus Torvalds committed
103 104 105
{
	proc_inode_cachep = kmem_cache_create("proc_inode_cache",
					     sizeof(struct proc_inode),
106
					     0, (SLAB_RECLAIM_ACCOUNT|
107
						SLAB_MEM_SPREAD|SLAB_PANIC),
108
					     init_once);
Linus Torvalds's avatar
Linus Torvalds committed
109 110
}

Vasiliy Kulikov's avatar
Vasiliy Kulikov committed
111 112
static int proc_show_options(struct seq_file *seq, struct dentry *root)
{
113 114 115
	struct super_block *sb = root->d_sb;
	struct pid_namespace *pid = sb->s_fs_info;

116 117
	if (!gid_eq(pid->pid_gid, GLOBAL_ROOT_GID))
		seq_printf(seq, ",gid=%u", from_kgid_munged(&init_user_ns, pid->pid_gid));
118 119 120
	if (pid->hide_pid != 0)
		seq_printf(seq, ",hidepid=%u", pid->hide_pid);

Vasiliy Kulikov's avatar
Vasiliy Kulikov committed
121 122 123
	return 0;
}

124
static const struct super_operations proc_sops = {
Linus Torvalds's avatar
Linus Torvalds committed
125 126 127
	.alloc_inode	= proc_alloc_inode,
	.destroy_inode	= proc_destroy_inode,
	.drop_inode	= generic_delete_inode,
Al Viro's avatar
Al Viro committed
128
	.evict_inode	= proc_evict_inode,
Linus Torvalds's avatar
Linus Torvalds committed
129
	.statfs		= simple_statfs,
Vasiliy Kulikov's avatar
Vasiliy Kulikov committed
130 131
	.remount_fs	= proc_remount,
	.show_options	= proc_show_options,
Linus Torvalds's avatar
Linus Torvalds committed
132 133
};

134 135 136 137
enum {BIAS = -1U<<31};

static inline int use_pde(struct proc_dir_entry *pde)
{
138
	return atomic_inc_unless_negative(&pde->in_use);
Alexey Dobriyan's avatar
Alexey Dobriyan committed
139 140
}

141
static void unuse_pde(struct proc_dir_entry *pde)
Alexey Dobriyan's avatar
Alexey Dobriyan committed
142
{
143 144
	if (atomic_dec_return(&pde->in_use) == BIAS)
		complete(pde->pde_unload_completion);
145 146
}

147 148 149
/* pde is locked */
static void close_pdeo(struct proc_dir_entry *pde, struct pde_opener *pdeo)
{
150
	if (pdeo->closing) {
151
		/* somebody else is doing that, just wait */
152 153
		DECLARE_COMPLETION_ONSTACK(c);
		pdeo->c = &c;
154
		spin_unlock(&pde->pde_unload_lock);
155
		wait_for_completion(&c);
156 157 158
		spin_lock(&pde->pde_unload_lock);
	} else {
		struct file *file;
159
		pdeo->closing = 1;
160 161 162 163 164
		spin_unlock(&pde->pde_unload_lock);
		file = pdeo->file;
		pde->proc_fops->release(file_inode(file), file);
		spin_lock(&pde->pde_unload_lock);
		list_del_init(&pdeo->lh);
165 166
		if (pdeo->c)
			complete(pdeo->c);
167
		kfree(pdeo);
168
	}
169 170
}

171
void proc_entry_rundown(struct proc_dir_entry *de)
172
{
173
	DECLARE_COMPLETION_ONSTACK(c);
174
	/* Wait until all existing callers into module are done. */
175 176 177
	de->pde_unload_completion = &c;
	if (atomic_add_return(BIAS, &de->in_use) != BIAS)
		wait_for_completion(&c);
178

179
	spin_lock(&de->pde_unload_lock);
180 181 182
	while (!list_empty(&de->pde_openers)) {
		struct pde_opener *pdeo;
		pdeo = list_first_entry(&de->pde_openers, struct pde_opener, lh);
183
		close_pdeo(de, pdeo);
184 185
	}
	spin_unlock(&de->pde_unload_lock);
186 187
}

188 189 190 191 192 193 194 195 196 197 198 199
static loff_t proc_reg_llseek(struct file *file, loff_t offset, int whence)
{
	struct proc_dir_entry *pde = PDE(file_inode(file));
	loff_t rv = -EINVAL;
	if (use_pde(pde)) {
		loff_t (*llseek)(struct file *, loff_t, int);
		llseek = pde->proc_fops->llseek;
		if (!llseek)
			llseek = default_llseek;
		rv = llseek(file, offset, whence);
		unuse_pde(pde);
	}
200 201 202
	return rv;
}

203
static ssize_t proc_reg_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
204
{
205
	ssize_t (*read)(struct file *, char __user *, size_t, loff_t *);
Al Viro's avatar
Al Viro committed
206
	struct proc_dir_entry *pde = PDE(file_inode(file));
207
	ssize_t rv = -EIO;
208 209 210 211 212
	if (use_pde(pde)) {
		read = pde->proc_fops->read;
		if (read)
			rv = read(file, buf, count, ppos);
		unuse_pde(pde);
213
	}
214 215
	return rv;
}
216

217 218 219 220 221 222 223 224 225 226 227
static ssize_t proc_reg_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
{
	ssize_t (*write)(struct file *, const char __user *, size_t, loff_t *);
	struct proc_dir_entry *pde = PDE(file_inode(file));
	ssize_t rv = -EIO;
	if (use_pde(pde)) {
		write = pde->proc_fops->write;
		if (write)
			rv = write(file, buf, count, ppos);
		unuse_pde(pde);
	}
228 229 230 231 232
	return rv;
}

static unsigned int proc_reg_poll(struct file *file, struct poll_table_struct *pts)
{
Al Viro's avatar
Al Viro committed
233
	struct proc_dir_entry *pde = PDE(file_inode(file));
234
	unsigned int rv = DEFAULT_POLLMASK;
235
	unsigned int (*poll)(struct file *, struct poll_table_struct *);
236 237 238 239 240
	if (use_pde(pde)) {
		poll = pde->proc_fops->poll;
		if (poll)
			rv = poll(file, pts);
		unuse_pde(pde);
241 242 243 244 245 246
	}
	return rv;
}

static long proc_reg_unlocked_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
Al Viro's avatar
Al Viro committed
247
	struct proc_dir_entry *pde = PDE(file_inode(file));
248
	long rv = -ENOTTY;
249
	long (*ioctl)(struct file *, unsigned int, unsigned long);
250 251 252 253 254
	if (use_pde(pde)) {
		ioctl = pde->proc_fops->unlocked_ioctl;
		if (ioctl)
			rv = ioctl(file, cmd, arg);
		unuse_pde(pde);
255 256 257 258 259 260 261
	}
	return rv;
}

#ifdef CONFIG_COMPAT
static long proc_reg_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
Al Viro's avatar
Al Viro committed
262
	struct proc_dir_entry *pde = PDE(file_inode(file));
263 264
	long rv = -ENOTTY;
	long (*compat_ioctl)(struct file *, unsigned int, unsigned long);
265 266 267 268 269
	if (use_pde(pde)) {
		compat_ioctl = pde->proc_fops->compat_ioctl;
		if (compat_ioctl)
			rv = compat_ioctl(file, cmd, arg);
		unuse_pde(pde);
270 271 272 273 274 275 276
	}
	return rv;
}
#endif

static int proc_reg_mmap(struct file *file, struct vm_area_struct *vma)
{
Al Viro's avatar
Al Viro committed
277
	struct proc_dir_entry *pde = PDE(file_inode(file));
278 279
	int rv = -EIO;
	int (*mmap)(struct file *, struct vm_area_struct *);
280 281 282 283 284
	if (use_pde(pde)) {
		mmap = pde->proc_fops->mmap;
		if (mmap)
			rv = mmap(file, vma);
		unuse_pde(pde);
285 286 287 288
	}
	return rv;
}

289 290 291
static unsigned long proc_reg_get_unmapped_area(struct file *file, unsigned long orig_addr, unsigned long len, unsigned long pgoff, unsigned long flags)
{
	struct proc_dir_entry *pde = PDE(file_inode(file));
292
	unsigned long rv = -EIO;
293
	unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long) = NULL;
294
	if (use_pde(pde)) {
295 296 297 298 299
#ifdef CONFIG_MMU
		get_unmapped_area = current->mm->get_unmapped_area;
#endif
		if (pde->proc_fops->get_unmapped_area)
			get_unmapped_area = pde->proc_fops->get_unmapped_area;
300 301 302 303 304 305 306
		if (get_unmapped_area)
			rv = get_unmapped_area(file, orig_addr, len, pgoff, flags);
		unuse_pde(pde);
	}
	return rv;
}

307 308 309 310 311
static int proc_reg_open(struct inode *inode, struct file *file)
{
	struct proc_dir_entry *pde = PDE(inode);
	int rv = 0;
	int (*open)(struct inode *, struct file *);
Alexey Dobriyan's avatar
Alexey Dobriyan committed
312 313 314 315 316 317 318 319 320 321 322 323 324
	int (*release)(struct inode *, struct file *);
	struct pde_opener *pdeo;

	/*
	 * What for, you ask? Well, we can have open, rmmod, remove_proc_entry
	 * sequence. ->release won't be called because ->proc_fops will be
	 * cleared. Depending on complexity of ->release, consequences vary.
	 *
	 * We can't wait for mercy when close will be done for real, it's
	 * deadlockable: rmmod foo </proc/foo . So, we're going to do ->release
	 * by hand in remove_proc_entry(). For this, save opener's credentials
	 * for later.
	 */
325
	pdeo = kzalloc(sizeof(struct pde_opener), GFP_KERNEL);
Alexey Dobriyan's avatar
Alexey Dobriyan committed
326 327
	if (!pdeo)
		return -ENOMEM;
328

329
	if (!use_pde(pde)) {
Alexey Dobriyan's avatar
Alexey Dobriyan committed
330
		kfree(pdeo);
331
		return -ENOENT;
332 333
	}
	open = pde->proc_fops->open;
Alexey Dobriyan's avatar
Alexey Dobriyan committed
334
	release = pde->proc_fops->release;
335 336 337 338

	if (open)
		rv = open(inode, file);

Alexey Dobriyan's avatar
Alexey Dobriyan committed
339 340 341 342
	if (rv == 0 && release) {
		/* To know what to release. */
		pdeo->file = file;
		/* Strictly for "too late" ->release in proc_reg_release(). */
343
		spin_lock(&pde->pde_unload_lock);
Alexey Dobriyan's avatar
Alexey Dobriyan committed
344
		list_add(&pdeo->lh, &pde->pde_openers);
345
		spin_unlock(&pde->pde_unload_lock);
Alexey Dobriyan's avatar
Alexey Dobriyan committed
346 347
	} else
		kfree(pdeo);
348 349

	unuse_pde(pde);
350 351 352 353 354 355
	return rv;
}

static int proc_reg_release(struct inode *inode, struct file *file)
{
	struct proc_dir_entry *pde = PDE(inode);
Alexey Dobriyan's avatar
Alexey Dobriyan committed
356
	struct pde_opener *pdeo;
357
	spin_lock(&pde->pde_unload_lock);
358 359 360 361 362
	list_for_each_entry(pdeo, &pde->pde_openers, lh) {
		if (pdeo->file == file) {
			close_pdeo(pde, pdeo);
			break;
		}
Alexey Dobriyan's avatar
Alexey Dobriyan committed
363
	}
364
	spin_unlock(&pde->pde_unload_lock);
365
	return 0;
366 367 368 369 370 371 372 373 374 375 376 377
}

static const struct file_operations proc_reg_file_ops = {
	.llseek		= proc_reg_llseek,
	.read		= proc_reg_read,
	.write		= proc_reg_write,
	.poll		= proc_reg_poll,
	.unlocked_ioctl	= proc_reg_unlocked_ioctl,
#ifdef CONFIG_COMPAT
	.compat_ioctl	= proc_reg_compat_ioctl,
#endif
	.mmap		= proc_reg_mmap,
378
	.get_unmapped_area = proc_reg_get_unmapped_area,
379 380 381 382
	.open		= proc_reg_open,
	.release	= proc_reg_release,
};

383 384 385 386 387 388 389 390
#ifdef CONFIG_COMPAT
static const struct file_operations proc_reg_file_ops_no_compat = {
	.llseek		= proc_reg_llseek,
	.read		= proc_reg_read,
	.write		= proc_reg_write,
	.poll		= proc_reg_poll,
	.unlocked_ioctl	= proc_reg_unlocked_ioctl,
	.mmap		= proc_reg_mmap,
391
	.get_unmapped_area = proc_reg_get_unmapped_area,
392 393 394 395 396
	.open		= proc_reg_open,
	.release	= proc_reg_release,
};
#endif

397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416
static void *proc_follow_link(struct dentry *dentry, struct nameidata *nd)
{
	struct proc_dir_entry *pde = PDE(dentry->d_inode);
	if (unlikely(!use_pde(pde)))
		return ERR_PTR(-EINVAL);
	nd_set_link(nd, pde->data);
	return pde;
}

static void proc_put_link(struct dentry *dentry, struct nameidata *nd, void *p)
{
	unuse_pde(p);
}

const struct inode_operations proc_link_inode_operations = {
	.readlink	= generic_readlink,
	.follow_link	= proc_follow_link,
	.put_link	= proc_put_link,
};

Alexey Dobriyan's avatar
Alexey Dobriyan committed
417
struct inode *proc_get_inode(struct super_block *sb, struct proc_dir_entry *de)
Linus Torvalds's avatar
Linus Torvalds committed
418
{
419
	struct inode *inode = new_inode_pseudo(sb);
Linus Torvalds's avatar
Linus Torvalds committed
420

421 422
	if (inode) {
		inode->i_ino = de->low_ino;
423 424
		inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
		PROC_I(inode)->pde = de;
425 426 427 428 429 430 431 432 433

		if (de->mode) {
			inode->i_mode = de->mode;
			inode->i_uid = de->uid;
			inode->i_gid = de->gid;
		}
		if (de->size)
			inode->i_size = de->size;
		if (de->nlink)
Miklos Szeredi's avatar
Miklos Szeredi committed
434
			set_nlink(inode, de->nlink);
435 436
		WARN_ON(!de->proc_iops);
		inode->i_op = de->proc_iops;
437 438
		if (de->proc_fops) {
			if (S_ISREG(inode->i_mode)) {
439
#ifdef CONFIG_COMPAT
440 441 442 443
				if (!de->proc_fops->compat_ioctl)
					inode->i_fop =
						&proc_reg_file_ops_no_compat;
				else
444
#endif
445 446 447
					inode->i_fop = &proc_reg_file_ops;
			} else {
				inode->i_fop = de->proc_fops;
448
			}
449
		}
450
	} else
451
	       pde_put(de);
Linus Torvalds's avatar
Linus Torvalds committed
452
	return inode;
453
}
Linus Torvalds's avatar
Linus Torvalds committed
454

455
int proc_fill_super(struct super_block *s)
Linus Torvalds's avatar
Linus Torvalds committed
456
{
457 458
	struct inode *root_inode;

459
	s->s_flags |= MS_NODIRATIME | MS_NOSUID | MS_NOEXEC;
Linus Torvalds's avatar
Linus Torvalds committed
460 461 462 463 464 465
	s->s_blocksize = 1024;
	s->s_blocksize_bits = 10;
	s->s_magic = PROC_SUPER_MAGIC;
	s->s_op = &proc_sops;
	s->s_time_gran = 1;
	
466
	pde_get(&proc_root);
467 468
	root_inode = proc_get_inode(s, &proc_root);
	if (!root_inode) {
Andrew Morton's avatar
Andrew Morton committed
469
		pr_err("proc_fill_super: get root inode failed\n");
470 471
		return -ENOMEM;
	}
Linus Torvalds's avatar
Linus Torvalds committed
472

473 474
	s->s_root = d_make_root(root_inode);
	if (!s->s_root) {
Andrew Morton's avatar
Andrew Morton committed
475
		pr_err("proc_fill_super: allocate dentry failed\n");
476 477 478
		return -ENOMEM;
	}

479
	return proc_setup_self(s);
Linus Torvalds's avatar
Linus Torvalds committed
480
}