aboutsummaryrefslogtreecommitdiffstats
path: root/fs/fcntl.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/fcntl.c')
-rw-r--r--fs/fcntl.c16
1 files changed, 11 insertions, 5 deletions
diff --git a/fs/fcntl.c b/fs/fcntl.c
index f9c03ca3b2f4..a040b764f8e3 100644
--- a/fs/fcntl.c
+++ b/fs/fcntl.c
@@ -428,14 +428,20 @@ static inline int sigio_perm(struct task_struct *p,
428} 428}
429 429
430static void send_sigio_to_task(struct task_struct *p, 430static void send_sigio_to_task(struct task_struct *p,
431 struct fown_struct *fown, 431 struct fown_struct *fown,
432 int fd, 432 int fd,
433 int reason) 433 int reason)
434{ 434{
435 if (!sigio_perm(p, fown, fown->signum)) 435 /*
436 * F_SETSIG can change ->signum lockless in parallel, make
437 * sure we read it once and use the same value throughout.
438 */
439 int signum = ACCESS_ONCE(fown->signum);
440
441 if (!sigio_perm(p, fown, signum))
436 return; 442 return;
437 443
438 switch (fown->signum) { 444 switch (signum) {
439 siginfo_t si; 445 siginfo_t si;
440 default: 446 default:
441 /* Queue a rt signal with the appropriate fd as its 447 /* Queue a rt signal with the appropriate fd as its
@@ -444,7 +450,7 @@ static void send_sigio_to_task(struct task_struct *p,
444 delivered even if we can't queue. Failure to 450 delivered even if we can't queue. Failure to
445 queue in this case _should_ be reported; we fall 451 queue in this case _should_ be reported; we fall
446 back to SIGIO in that case. --sct */ 452 back to SIGIO in that case. --sct */
447 si.si_signo = fown->signum; 453 si.si_signo = signum;
448 si.si_errno = 0; 454 si.si_errno = 0;
449 si.si_code = reason; 455 si.si_code = reason;
450 /* Make sure we are called with one of the POLL_* 456 /* Make sure we are called with one of the POLL_*
@@ -456,7 +462,7 @@ static void send_sigio_to_task(struct task_struct *p,
456 else 462 else
457 si.si_band = band_table[reason - POLL_IN]; 463 si.si_band = band_table[reason - POLL_IN];
458 si.si_fd = fd; 464 si.si_fd = fd;
459 if (!group_send_sig_info(fown->signum, &si, p)) 465 if (!group_send_sig_info(signum, &si, p))
460 break; 466 break;
461 /* fall-through: fall back on the old plain SIGIO signal */ 467 /* fall-through: fall back on the old plain SIGIO signal */
462 case 0: 468 case 0: