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

#include <linux/syscalls.h>
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/fs.h>
#include <linux/file.h>
Al Viro's avatar
Al Viro committed
12
#include <linux/fdtable.h>
13
#include <linux/capability.h>
Linus Torvalds's avatar
Linus Torvalds committed
14
15
16
#include <linux/dnotify.h>
#include <linux/slab.h>
#include <linux/module.h>
17
#include <linux/pipe_fs_i.h>
Linus Torvalds's avatar
Linus Torvalds committed
18
19
#include <linux/security.h>
#include <linux/ptrace.h>
20
#include <linux/signal.h>
21
#include <linux/rcupdate.h>
22
#include <linux/pid_namespace.h>
Linus Torvalds's avatar
Linus Torvalds committed
23
24
25
26
27

#include <asm/poll.h>
#include <asm/siginfo.h>
#include <asm/uaccess.h>

28
void set_close_on_exec(unsigned int fd, int flag)
Linus Torvalds's avatar
Linus Torvalds committed
29
30
{
	struct files_struct *files = current->files;
31
	struct fdtable *fdt;
Linus Torvalds's avatar
Linus Torvalds committed
32
	spin_lock(&files->file_lock);
33
	fdt = files_fdtable(files);
Linus Torvalds's avatar
Linus Torvalds committed
34
	if (flag)
35
		FD_SET(fd, fdt->close_on_exec);
Linus Torvalds's avatar
Linus Torvalds committed
36
	else
37
		FD_CLR(fd, fdt->close_on_exec);
Linus Torvalds's avatar
Linus Torvalds committed
38
39
40
	spin_unlock(&files->file_lock);
}

41
static int get_close_on_exec(unsigned int fd)
Linus Torvalds's avatar
Linus Torvalds committed
42
43
{
	struct files_struct *files = current->files;
44
	struct fdtable *fdt;
Linus Torvalds's avatar
Linus Torvalds committed
45
	int res;
46
	rcu_read_lock();
47
48
	fdt = files_fdtable(files);
	res = FD_ISSET(fd, fdt->close_on_exec);
49
	rcu_read_unlock();
Linus Torvalds's avatar
Linus Torvalds committed
50
51
52
	return res;
}

53
SYSCALL_DEFINE3(dup3, unsigned int, oldfd, unsigned int, newfd, int, flags)
Linus Torvalds's avatar
Linus Torvalds committed
54
55
56
57
{
	int err = -EBADF;
	struct file * file, *tofree;
	struct files_struct * files = current->files;
58
	struct fdtable *fdt;
Linus Torvalds's avatar
Linus Torvalds committed
59

Ulrich Drepper's avatar
Ulrich Drepper committed
60
61
62
	if ((flags & ~O_CLOEXEC) != 0)
		return -EINVAL;

63
64
65
	if (unlikely(oldfd == newfd))
		return -EINVAL;

Linus Torvalds's avatar
Linus Torvalds committed
66
67
	spin_lock(&files->file_lock);
	err = expand_files(files, newfd);
Al Viro's avatar
Al Viro committed
68
69
70
	file = fcheck(oldfd);
	if (unlikely(!file))
		goto Ebadf;
Al Viro's avatar
Al Viro committed
71
72
	if (unlikely(err < 0)) {
		if (err == -EMFILE)
Al Viro's avatar
Al Viro committed
73
74
			goto Ebadf;
		goto out_unlock;
Al Viro's avatar
Al Viro committed
75
	}
Al Viro's avatar
Al Viro committed
76
77
78
79
80
81
82
83
84
85
86
87
88
89
	/*
	 * We need to detect attempts to do dup2() over allocated but still
	 * not finished descriptor.  NB: OpenBSD avoids that at the price of
	 * extra work in their equivalent of fget() - they insert struct
	 * file immediately after grabbing descriptor, mark it larval if
	 * more work (e.g. actual opening) is needed and make sure that
	 * fget() treats larval files as absent.  Potentially interesting,
	 * but while extra work in fget() is trivial, locking implications
	 * and amount of surgery on open()-related paths in VFS are not.
	 * FreeBSD fails with -EBADF in the same situation, NetBSD "solution"
	 * deadlocks in rather amusing ways, AFAICS.  All of that is out of
	 * scope of POSIX or SUS, since neither considers shared descriptor
	 * tables and this condition does not arise without those.
	 */
Linus Torvalds's avatar
Linus Torvalds committed
90
	err = -EBUSY;
91
92
93
	fdt = files_fdtable(files);
	tofree = fdt->fd[newfd];
	if (!tofree && FD_ISSET(newfd, fdt->open_fds))
Al Viro's avatar
Al Viro committed
94
95
		goto out_unlock;
	get_file(file);
96
	rcu_assign_pointer(fdt->fd[newfd], file);
97
	FD_SET(newfd, fdt->open_fds);
Ulrich Drepper's avatar
Ulrich Drepper committed
98
99
100
101
	if (flags & O_CLOEXEC)
		FD_SET(newfd, fdt->close_on_exec);
	else
		FD_CLR(newfd, fdt->close_on_exec);
Linus Torvalds's avatar
Linus Torvalds committed
102
103
104
105
106
	spin_unlock(&files->file_lock);

	if (tofree)
		filp_close(tofree, files);

Al Viro's avatar
Al Viro committed
107
108
109
110
111
	return newfd;

Ebadf:
	err = -EBADF;
out_unlock:
Linus Torvalds's avatar
Linus Torvalds committed
112
	spin_unlock(&files->file_lock);
Al Viro's avatar
Al Viro committed
113
	return err;
Linus Torvalds's avatar
Linus Torvalds committed
114
}
Ulrich Drepper's avatar
Ulrich Drepper committed
115

116
SYSCALL_DEFINE2(dup2, unsigned int, oldfd, unsigned int, newfd)
Ulrich Drepper's avatar
Ulrich Drepper committed
117
{
118
119
	if (unlikely(newfd == oldfd)) { /* corner case */
		struct files_struct *files = current->files;
120
121
		int retval = oldfd;

122
123
		rcu_read_lock();
		if (!fcheck_files(files, oldfd))
124
			retval = -EBADF;
125
		rcu_read_unlock();
126
		return retval;
127
	}
Ulrich Drepper's avatar
Ulrich Drepper committed
128
129
	return sys_dup3(oldfd, newfd, 0);
}
Linus Torvalds's avatar
Linus Torvalds committed
130

131
SYSCALL_DEFINE1(dup, unsigned int, fildes)
Linus Torvalds's avatar
Linus Torvalds committed
132
133
{
	int ret = -EBADF;
134
135
136
137
138
139
140
141
142
	struct file *file = fget(fildes);

	if (file) {
		ret = get_unused_fd();
		if (ret >= 0)
			fd_install(ret, file);
		else
			fput(file);
	}
Linus Torvalds's avatar
Linus Torvalds committed
143
144
145
	return ret;
}

146
#define SETFL_MASK (O_APPEND | O_NONBLOCK | O_NDELAY | O_DIRECT | O_NOATIME)
Linus Torvalds's avatar
Linus Torvalds committed
147
148
149

static int setfl(int fd, struct file * filp, unsigned long arg)
{
150
	struct inode * inode = filp->f_path.dentry->d_inode;
Linus Torvalds's avatar
Linus Torvalds committed
151
152
	int error = 0;

153
154
155
156
157
	/*
	 * O_APPEND cannot be cleared if the file is marked as append-only
	 * and the file is open for write.
	 */
	if (((arg ^ filp->f_flags) & O_APPEND) && IS_APPEND(inode))
Linus Torvalds's avatar
Linus Torvalds committed
158
159
160
161
		return -EPERM;

	/* O_NOATIME can only be set by the owner or superuser */
	if ((arg & O_NOATIME) && !(filp->f_flags & O_NOATIME))
162
		if (!is_owner_or_cap(inode))
Linus Torvalds's avatar
Linus Torvalds committed
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
			return -EPERM;

	/* required for strict SunOS emulation */
	if (O_NONBLOCK != O_NDELAY)
	       if (arg & O_NDELAY)
		   arg |= O_NONBLOCK;

	if (arg & O_DIRECT) {
		if (!filp->f_mapping || !filp->f_mapping->a_ops ||
			!filp->f_mapping->a_ops->direct_IO)
				return -EINVAL;
	}

	if (filp->f_op && filp->f_op->check_flags)
		error = filp->f_op->check_flags(arg);
	if (error)
		return error;

181
	/*
182
	 * ->fasync() is responsible for setting the FASYNC bit.
183
	 */
184
185
186
187
188
	if (((arg ^ filp->f_flags) & FASYNC) && filp->f_op &&
			filp->f_op->fasync) {
		error = filp->f_op->fasync(fd, filp, (arg & FASYNC) != 0);
		if (error < 0)
			goto out;
189
190
		if (error > 0)
			error = 0;
Linus Torvalds's avatar
Linus Torvalds committed
191
	}
192
	spin_lock(&filp->f_lock);
Linus Torvalds's avatar
Linus Torvalds committed
193
	filp->f_flags = (arg & SETFL_MASK) | (filp->f_flags & ~SETFL_MASK);
194
	spin_unlock(&filp->f_lock);
195

Linus Torvalds's avatar
Linus Torvalds committed
196
197
198
199
 out:
	return error;
}

200
static void f_modown(struct file *filp, struct pid *pid, enum pid_type type,
201
                     int force)
Linus Torvalds's avatar
Linus Torvalds committed
202
{
203
	write_lock_irq(&filp->f_owner.lock);
Linus Torvalds's avatar
Linus Torvalds committed
204
	if (force || !filp->f_owner.pid) {
205
206
207
		put_pid(filp->f_owner.pid);
		filp->f_owner.pid = get_pid(pid);
		filp->f_owner.pid_type = type;
208
209
210
211
212
213

		if (pid) {
			const struct cred *cred = current_cred();
			filp->f_owner.uid = cred->uid;
			filp->f_owner.euid = cred->euid;
		}
Linus Torvalds's avatar
Linus Torvalds committed
214
	}
215
	write_unlock_irq(&filp->f_owner.lock);
Linus Torvalds's avatar
Linus Torvalds committed
216
217
}

218
219
int __f_setown(struct file *filp, struct pid *pid, enum pid_type type,
		int force)
Linus Torvalds's avatar
Linus Torvalds committed
220
221
{
	int err;
222

Linus Torvalds's avatar
Linus Torvalds committed
223
224
225
226
	err = security_file_set_fowner(filp);
	if (err)
		return err;

227
	f_modown(filp, pid, type, force);
Linus Torvalds's avatar
Linus Torvalds committed
228
229
	return 0;
}
230
EXPORT_SYMBOL(__f_setown);
Linus Torvalds's avatar
Linus Torvalds committed
231

232
233
234
235
236
237
238
239
240
241
242
243
int f_setown(struct file *filp, unsigned long arg, int force)
{
	enum pid_type type;
	struct pid *pid;
	int who = arg;
	int result;
	type = PIDTYPE_PID;
	if (who < 0) {
		type = PIDTYPE_PGID;
		who = -who;
	}
	rcu_read_lock();
244
	pid = find_vpid(who);
245
246
247
248
	result = __f_setown(filp, pid, type, force);
	rcu_read_unlock();
	return result;
}
Linus Torvalds's avatar
Linus Torvalds committed
249
250
251
252
EXPORT_SYMBOL(f_setown);

void f_delown(struct file *filp)
{
253
	f_modown(filp, NULL, PIDTYPE_PID, 1);
254
255
256
257
258
}

pid_t f_getown(struct file *filp)
{
	pid_t pid;
259
	read_lock(&filp->f_owner.lock);
260
	pid = pid_vnr(filp->f_owner.pid);
261
262
	if (filp->f_owner.pid_type == PIDTYPE_PGID)
		pid = -pid;
263
	read_unlock(&filp->f_owner.lock);
264
	return pid;
Linus Torvalds's avatar
Linus Torvalds committed
265
266
}

Peter Zijlstra's avatar
Peter Zijlstra committed
267
268
269
270
271
272
273
274
275
276
static int f_setown_ex(struct file *filp, unsigned long arg)
{
	struct f_owner_ex * __user owner_p = (void * __user)arg;
	struct f_owner_ex owner;
	struct pid *pid;
	int type;
	int ret;

	ret = copy_from_user(&owner, owner_p, sizeof(owner));
	if (ret)
277
		return -EFAULT;
Peter Zijlstra's avatar
Peter Zijlstra committed
278
279
280
281
282
283
284
285
286
287

	switch (owner.type) {
	case F_OWNER_TID:
		type = PIDTYPE_MAX;
		break;

	case F_OWNER_PID:
		type = PIDTYPE_PID;
		break;

288
	case F_OWNER_PGRP:
Peter Zijlstra's avatar
Peter Zijlstra committed
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
		type = PIDTYPE_PGID;
		break;

	default:
		return -EINVAL;
	}

	rcu_read_lock();
	pid = find_vpid(owner.pid);
	if (owner.pid && !pid)
		ret = -ESRCH;
	else
		ret = __f_setown(filp, pid, type, 1);
	rcu_read_unlock();

	return ret;
}

static int f_getown_ex(struct file *filp, unsigned long arg)
{
	struct f_owner_ex * __user owner_p = (void * __user)arg;
	struct f_owner_ex owner;
	int ret = 0;

	read_lock(&filp->f_owner.lock);
	owner.pid = pid_vnr(filp->f_owner.pid);
	switch (filp->f_owner.pid_type) {
	case PIDTYPE_MAX:
		owner.type = F_OWNER_TID;
		break;

	case PIDTYPE_PID:
		owner.type = F_OWNER_PID;
		break;

	case PIDTYPE_PGID:
325
		owner.type = F_OWNER_PGRP;
Peter Zijlstra's avatar
Peter Zijlstra committed
326
327
328
329
330
331
332
333
334
		break;

	default:
		WARN_ON(1);
		ret = -EINVAL;
		break;
	}
	read_unlock(&filp->f_owner.lock);

335
	if (!ret) {
Peter Zijlstra's avatar
Peter Zijlstra committed
336
		ret = copy_to_user(owner_p, &owner, sizeof(owner));
337
338
339
		if (ret)
			ret = -EFAULT;
	}
Peter Zijlstra's avatar
Peter Zijlstra committed
340
341
342
	return ret;
}

Linus Torvalds's avatar
Linus Torvalds committed
343
344
345
346
347
348
349
static long do_fcntl(int fd, unsigned int cmd, unsigned long arg,
		struct file *filp)
{
	long err = -EINVAL;

	switch (cmd) {
	case F_DUPFD:
350
	case F_DUPFD_CLOEXEC:
Jiri Slaby's avatar
Jiri Slaby committed
351
		if (arg >= rlimit(RLIMIT_NOFILE))
Al Viro's avatar
Al Viro committed
352
			break;
353
354
355
356
357
		err = alloc_fd(arg, cmd == F_DUPFD_CLOEXEC ? O_CLOEXEC : 0);
		if (err >= 0) {
			get_file(filp);
			fd_install(err, filp);
		}
Linus Torvalds's avatar
Linus Torvalds committed
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
		break;
	case F_GETFD:
		err = get_close_on_exec(fd) ? FD_CLOEXEC : 0;
		break;
	case F_SETFD:
		err = 0;
		set_close_on_exec(fd, arg & FD_CLOEXEC);
		break;
	case F_GETFL:
		err = filp->f_flags;
		break;
	case F_SETFL:
		err = setfl(fd, filp, arg);
		break;
	case F_GETLK:
		err = fcntl_getlk(filp, (struct flock __user *) arg);
		break;
	case F_SETLK:
	case F_SETLKW:
377
		err = fcntl_setlk(fd, filp, cmd, (struct flock __user *) arg);
Linus Torvalds's avatar
Linus Torvalds committed
378
379
380
381
382
383
384
385
386
		break;
	case F_GETOWN:
		/*
		 * XXX If f_owner is a process group, the
		 * negative return value will get converted
		 * into an error.  Oops.  If we keep the
		 * current syscall conventions, the only way
		 * to fix this will be in libc.
		 */
387
		err = f_getown(filp);
Linus Torvalds's avatar
Linus Torvalds committed
388
389
390
391
392
		force_successful_syscall_return();
		break;
	case F_SETOWN:
		err = f_setown(filp, arg, 1);
		break;
Peter Zijlstra's avatar
Peter Zijlstra committed
393
394
395
396
397
398
	case F_GETOWN_EX:
		err = f_getown_ex(filp, arg);
		break;
	case F_SETOWN_EX:
		err = f_setown_ex(filp, arg);
		break;
Linus Torvalds's avatar
Linus Torvalds committed
399
400
401
402
403
	case F_GETSIG:
		err = filp->f_owner.signum;
		break;
	case F_SETSIG:
		/* arg == 0 restores default behaviour. */
404
		if (!valid_signal(arg)) {
Linus Torvalds's avatar
Linus Torvalds committed
405
406
407
408
409
410
411
412
413
414
415
416
417
418
			break;
		}
		err = 0;
		filp->f_owner.signum = arg;
		break;
	case F_GETLEASE:
		err = fcntl_getlease(filp);
		break;
	case F_SETLEASE:
		err = fcntl_setlease(fd, filp, arg);
		break;
	case F_NOTIFY:
		err = fcntl_dirnotify(fd, filp, arg);
		break;
419
420
421
422
	case F_SETPIPE_SZ:
	case F_GETPIPE_SZ:
		err = pipe_fcntl(filp, cmd, arg);
		break;
Linus Torvalds's avatar
Linus Torvalds committed
423
424
425
426
427
428
	default:
		break;
	}
	return err;
}

429
SYSCALL_DEFINE3(fcntl, unsigned int, fd, unsigned int, cmd, unsigned long, arg)
Linus Torvalds's avatar
Linus Torvalds committed
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
{	
	struct file *filp;
	long err = -EBADF;

	filp = fget(fd);
	if (!filp)
		goto out;

	err = security_file_fcntl(filp, cmd, arg);
	if (err) {
		fput(filp);
		return err;
	}

	err = do_fcntl(fd, cmd, arg, filp);

 	fput(filp);
out:
	return err;
}

#if BITS_PER_LONG == 32
452
453
SYSCALL_DEFINE3(fcntl64, unsigned int, fd, unsigned int, cmd,
		unsigned long, arg)
Linus Torvalds's avatar
Linus Torvalds committed
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
{	
	struct file * filp;
	long err;

	err = -EBADF;
	filp = fget(fd);
	if (!filp)
		goto out;

	err = security_file_fcntl(filp, cmd, arg);
	if (err) {
		fput(filp);
		return err;
	}
	err = -EBADF;
	
	switch (cmd) {
		case F_GETLK64:
			err = fcntl_getlk64(filp, (struct flock64 __user *) arg);
			break;
		case F_SETLK64:
		case F_SETLKW64:
476
477
			err = fcntl_setlk64(fd, filp, cmd,
					(struct flock64 __user *) arg);
Linus Torvalds's avatar
Linus Torvalds committed
478
479
480
481
482
483
484
485
486
487
488
489
490
			break;
		default:
			err = do_fcntl(fd, cmd, arg, filp);
			break;
	}
	fput(filp);
out:
	return err;
}
#endif

/* Table to convert sigio signal codes into poll band bitmaps */

491
static const long band_table[NSIGPOLL] = {
Linus Torvalds's avatar
Linus Torvalds committed
492
493
494
495
496
497
498
499
500
501
502
	POLLIN | POLLRDNORM,			/* POLL_IN */
	POLLOUT | POLLWRNORM | POLLWRBAND,	/* POLL_OUT */
	POLLIN | POLLRDNORM | POLLMSG,		/* POLL_MSG */
	POLLERR,				/* POLL_ERR */
	POLLPRI | POLLRDBAND,			/* POLL_PRI */
	POLLHUP | POLLERR			/* POLL_HUP */
};

static inline int sigio_perm(struct task_struct *p,
                             struct fown_struct *fown, int sig)
{
503
504
505
506
507
508
509
510
511
512
513
	const struct cred *cred;
	int ret;

	rcu_read_lock();
	cred = __task_cred(p);
	ret = ((fown->euid == 0 ||
		fown->euid == cred->suid || fown->euid == cred->uid ||
		fown->uid  == cred->suid || fown->uid  == cred->uid) &&
	       !security_file_send_sigiotask(p, fown, sig));
	rcu_read_unlock();
	return ret;
Linus Torvalds's avatar
Linus Torvalds committed
514
515
516
}

static void send_sigio_to_task(struct task_struct *p,
517
			       struct fown_struct *fown,
Peter Zijlstra's avatar
Peter Zijlstra committed
518
			       int fd, int reason, int group)
Linus Torvalds's avatar
Linus Torvalds committed
519
{
520
521
522
523
524
525
526
	/*
	 * F_SETSIG can change ->signum lockless in parallel, make
	 * sure we read it once and use the same value throughout.
	 */
	int signum = ACCESS_ONCE(fown->signum);

	if (!sigio_perm(p, fown, signum))
Linus Torvalds's avatar
Linus Torvalds committed
527
528
		return;

529
	switch (signum) {
Linus Torvalds's avatar
Linus Torvalds committed
530
531
532
533
534
535
536
537
		siginfo_t si;
		default:
			/* Queue a rt signal with the appropriate fd as its
			   value.  We use SI_SIGIO as the source, not 
			   SI_KERNEL, since kernel signals always get 
			   delivered even if we can't queue.  Failure to
			   queue in this case _should_ be reported; we fall
			   back to SIGIO in that case. --sct */
538
			si.si_signo = signum;
Linus Torvalds's avatar
Linus Torvalds committed
539
540
541
542
543
			si.si_errno = 0;
		        si.si_code  = reason;
			/* Make sure we are called with one of the POLL_*
			   reasons, otherwise we could leak kernel stack into
			   userspace.  */
544
			BUG_ON((reason & __SI_MASK) != __SI_POLL);
Linus Torvalds's avatar
Linus Torvalds committed
545
546
547
548
549
			if (reason - POLL_IN >= NSIGPOLL)
				si.si_band  = ~0L;
			else
				si.si_band = band_table[reason - POLL_IN];
			si.si_fd    = fd;
Peter Zijlstra's avatar
Peter Zijlstra committed
550
			if (!do_send_sig_info(signum, &si, p, group))
Linus Torvalds's avatar
Linus Torvalds committed
551
552
553
				break;
		/* fall-through: fall back on the old plain SIGIO signal */
		case 0:
Peter Zijlstra's avatar
Peter Zijlstra committed
554
			do_send_sig_info(SIGIO, SEND_SIG_PRIV, p, group);
Linus Torvalds's avatar
Linus Torvalds committed
555
556
557
558
559
560
	}
}

void send_sigio(struct fown_struct *fown, int fd, int band)
{
	struct task_struct *p;
561
562
	enum pid_type type;
	struct pid *pid;
Peter Zijlstra's avatar
Peter Zijlstra committed
563
	int group = 1;
Linus Torvalds's avatar
Linus Torvalds committed
564
565
	
	read_lock(&fown->lock);
Peter Zijlstra's avatar
Peter Zijlstra committed
566

567
	type = fown->pid_type;
Peter Zijlstra's avatar
Peter Zijlstra committed
568
569
570
571
572
	if (type == PIDTYPE_MAX) {
		group = 0;
		type = PIDTYPE_PID;
	}

Linus Torvalds's avatar
Linus Torvalds committed
573
574
575
576
577
	pid = fown->pid;
	if (!pid)
		goto out_unlock_fown;
	
	read_lock(&tasklist_lock);
578
	do_each_pid_task(pid, type, p) {
Peter Zijlstra's avatar
Peter Zijlstra committed
579
		send_sigio_to_task(p, fown, fd, band, group);
580
	} while_each_pid_task(pid, type, p);
Linus Torvalds's avatar
Linus Torvalds committed
581
582
583
584
585
586
	read_unlock(&tasklist_lock);
 out_unlock_fown:
	read_unlock(&fown->lock);
}

static void send_sigurg_to_task(struct task_struct *p,
Peter Zijlstra's avatar
Peter Zijlstra committed
587
				struct fown_struct *fown, int group)
Linus Torvalds's avatar
Linus Torvalds committed
588
589
{
	if (sigio_perm(p, fown, SIGURG))
Peter Zijlstra's avatar
Peter Zijlstra committed
590
		do_send_sig_info(SIGURG, SEND_SIG_PRIV, p, group);
Linus Torvalds's avatar
Linus Torvalds committed
591
592
593
594
595
}

int send_sigurg(struct fown_struct *fown)
{
	struct task_struct *p;
596
597
	enum pid_type type;
	struct pid *pid;
Peter Zijlstra's avatar
Peter Zijlstra committed
598
	int group = 1;
599
	int ret = 0;
Linus Torvalds's avatar
Linus Torvalds committed
600
601
	
	read_lock(&fown->lock);
Peter Zijlstra's avatar
Peter Zijlstra committed
602

603
	type = fown->pid_type;
Peter Zijlstra's avatar
Peter Zijlstra committed
604
605
606
607
608
	if (type == PIDTYPE_MAX) {
		group = 0;
		type = PIDTYPE_PID;
	}

Linus Torvalds's avatar
Linus Torvalds committed
609
610
611
612
613
614
615
	pid = fown->pid;
	if (!pid)
		goto out_unlock_fown;

	ret = 1;
	
	read_lock(&tasklist_lock);
616
	do_each_pid_task(pid, type, p) {
Peter Zijlstra's avatar
Peter Zijlstra committed
617
		send_sigurg_to_task(p, fown, group);
618
	} while_each_pid_task(pid, type, p);
Linus Torvalds's avatar
Linus Torvalds committed
619
620
621
622
623
624
	read_unlock(&tasklist_lock);
 out_unlock_fown:
	read_unlock(&fown->lock);
	return ret;
}

625
static DEFINE_SPINLOCK(fasync_lock);
626
static struct kmem_cache *fasync_cache __read_mostly;
Linus Torvalds's avatar
Linus Torvalds committed
627

628
629
630
631
632
633
static void fasync_free_rcu(struct rcu_head *head)
{
	kmem_cache_free(fasync_cache,
			container_of(head, struct fasync_struct, fa_rcu));
}

Linus Torvalds's avatar
Linus Torvalds committed
634
/*
635
636
637
638
639
640
641
 * Remove a fasync entry. If successfully removed, return
 * positive and clear the FASYNC flag. If no entry exists,
 * do nothing and return 0.
 *
 * NOTE! It is very important that the FASYNC flag always
 * match the state "is the filp on a fasync list".
 *
Linus Torvalds's avatar
Linus Torvalds committed
642
 */
643
static int fasync_remove_entry(struct file *filp, struct fasync_struct **fapp)
Linus Torvalds's avatar
Linus Torvalds committed
644
645
646
647
{
	struct fasync_struct *fa, **fp;
	int result = 0;

648
	spin_lock(&filp->f_lock);
649
	spin_lock(&fasync_lock);
650
651
652
	for (fp = fapp; (fa = *fp) != NULL; fp = &fa->fa_next) {
		if (fa->fa_file != filp)
			continue;
653
654
655
656
657

		spin_lock_irq(&fa->fa_lock);
		fa->fa_file = NULL;
		spin_unlock_irq(&fa->fa_lock);

658
		*fp = fa->fa_next;
659
		call_rcu(&fa->fa_rcu, fasync_free_rcu);
660
661
662
		filp->f_flags &= ~FASYNC;
		result = 1;
		break;
Linus Torvalds's avatar
Linus Torvalds committed
663
	}
664
	spin_unlock(&fasync_lock);
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
	spin_unlock(&filp->f_lock);
	return result;
}

/*
 * Add a fasync entry. Return negative on error, positive if
 * added, and zero if did nothing but change an existing one.
 *
 * NOTE! It is very important that the FASYNC flag always
 * match the state "is the filp on a fasync list".
 */
static int fasync_add_entry(int fd, struct file *filp, struct fasync_struct **fapp)
{
	struct fasync_struct *new, *fa, **fp;
	int result = 0;

	new = kmem_cache_alloc(fasync_cache, GFP_KERNEL);
	if (!new)
		return -ENOMEM;
684
685

	spin_lock(&filp->f_lock);
686
	spin_lock(&fasync_lock);
Linus Torvalds's avatar
Linus Torvalds committed
687
	for (fp = fapp; (fa = *fp) != NULL; fp = &fa->fa_next) {
688
689
		if (fa->fa_file != filp)
			continue;
690
691

		spin_lock_irq(&fa->fa_lock);
692
		fa->fa_fd = fd;
693
694
		spin_unlock_irq(&fa->fa_lock);

695
696
		kmem_cache_free(fasync_cache, new);
		goto out;
Linus Torvalds's avatar
Linus Torvalds committed
697
698
	}

699
	spin_lock_init(&new->fa_lock);
700
701
702
703
	new->magic = FASYNC_MAGIC;
	new->fa_file = filp;
	new->fa_fd = fd;
	new->fa_next = *fapp;
704
	rcu_assign_pointer(*fapp, new);
705
706
707
	result = 1;
	filp->f_flags |= FASYNC;

Linus Torvalds's avatar
Linus Torvalds committed
708
out:
709
	spin_unlock(&fasync_lock);
710
	spin_unlock(&filp->f_lock);
Linus Torvalds's avatar
Linus Torvalds committed
711
712
713
	return result;
}

714
715
716
717
718
719
720
721
722
723
724
725
726
/*
 * fasync_helper() is used by almost all character device drivers
 * to set up the fasync queue, and for regular files by the file
 * lease code. It returns negative on error, 0 if it did no changes
 * and positive if it added/deleted the entry.
 */
int fasync_helper(int fd, struct file * filp, int on, struct fasync_struct **fapp)
{
	if (!on)
		return fasync_remove_entry(filp, fapp);
	return fasync_add_entry(fd, filp, fapp);
}

Linus Torvalds's avatar
Linus Torvalds committed
727
728
EXPORT_SYMBOL(fasync_helper);

729
730
731
732
/*
 * rcu_read_lock() is held
 */
static void kill_fasync_rcu(struct fasync_struct *fa, int sig, int band)
Linus Torvalds's avatar
Linus Torvalds committed
733
734
{
	while (fa) {
735
		struct fown_struct *fown;
736
737
		unsigned long flags;

Linus Torvalds's avatar
Linus Torvalds committed
738
739
740
741
742
		if (fa->magic != FASYNC_MAGIC) {
			printk(KERN_ERR "kill_fasync: bad magic number in "
			       "fasync_struct!\n");
			return;
		}
743
		spin_lock_irqsave(&fa->fa_lock, flags);
744
745
746
747
748
749
750
751
		if (fa->fa_file) {
			fown = &fa->fa_file->f_owner;
			/* Don't send SIGURG to processes which have not set a
			   queued signum: SIGURG has its own default signalling
			   mechanism. */
			if (!(sig == SIGURG && fown->signum == 0))
				send_sigio(fown, fa->fa_fd, band);
		}
752
		spin_unlock_irqrestore(&fa->fa_lock, flags);
753
		fa = rcu_dereference(fa->fa_next);
Linus Torvalds's avatar
Linus Torvalds committed
754
755
756
757
758
759
760
761
762
	}
}

void kill_fasync(struct fasync_struct **fp, int sig, int band)
{
	/* First a quick test without locking: usually
	 * the list is empty.
	 */
	if (*fp) {
763
764
765
		rcu_read_lock();
		kill_fasync_rcu(rcu_dereference(*fp), sig, band);
		rcu_read_unlock();
Linus Torvalds's avatar
Linus Torvalds committed
766
767
768
769
770
771
772
	}
}
EXPORT_SYMBOL(kill_fasync);

static int __init fasync_init(void)
{
	fasync_cache = kmem_cache_create("fasync_cache",
773
		sizeof(struct fasync_struct), 0, SLAB_PANIC, NULL);
Linus Torvalds's avatar
Linus Torvalds committed
774
775
776
777
	return 0;
}

module_init(fasync_init)