linux/fs/signalfd.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 *  fs/signalfd.c
   4 *
   5 *  Copyright (C) 2003  Linus Torvalds
   6 *
   7 *  Mon Mar 5, 2007: Davide Libenzi <davidel@xmailserver.org>
   8 *      Changed ->read() to return a siginfo strcture instead of signal number.
   9 *      Fixed locking in ->poll().
  10 *      Added sighand-detach notification.
  11 *      Added fd re-use in sys_signalfd() syscall.
  12 *      Now using anonymous inode source.
  13 *      Thanks to Oleg Nesterov for useful code review and suggestions.
  14 *      More comments and suggestions from Arnd Bergmann.
  15 *  Sat May 19, 2007: Davi E. M. Arnaut <davi@haxent.com.br>
  16 *      Retrieve multiple signals with one read() call
  17 *  Sun Jul 15, 2007: Davide Libenzi <davidel@xmailserver.org>
  18 *      Attach to the sighand only during read() and poll().
  19 */
  20
  21#include <linux/file.h>
  22#include <linux/poll.h>
  23#include <linux/init.h>
  24#include <linux/fs.h>
  25#include <linux/sched.h>
  26#include <linux/slab.h>
  27#include <linux/kernel.h>
  28#include <linux/signal.h>
  29#include <linux/list.h>
  30#include <linux/anon_inodes.h>
  31#include <linux/signalfd.h>
  32#include <linux/syscalls.h>
  33#include <linux/proc_fs.h>
  34#include <linux/compat.h>
  35
  36void signalfd_cleanup(struct sighand_struct *sighand)
  37{
  38        wake_up_pollfree(&sighand->signalfd_wqh);
  39}
  40
  41struct signalfd_ctx {
  42        sigset_t sigmask;
  43};
  44
  45static int signalfd_release(struct inode *inode, struct file *file)
  46{
  47        kfree(file->private_data);
  48        return 0;
  49}
  50
  51static __poll_t signalfd_poll(struct file *file, poll_table *wait)
  52{
  53        struct signalfd_ctx *ctx = file->private_data;
  54        __poll_t events = 0;
  55
  56        poll_wait(file, &current->sighand->signalfd_wqh, wait);
  57
  58        spin_lock_irq(&current->sighand->siglock);
  59        if (next_signal(&current->pending, &ctx->sigmask) ||
  60            next_signal(&current->signal->shared_pending,
  61                        &ctx->sigmask))
  62                events |= EPOLLIN;
  63        spin_unlock_irq(&current->sighand->siglock);
  64
  65        return events;
  66}
  67
  68/*
  69 * Copied from copy_siginfo_to_user() in kernel/signal.c
  70 */
  71static int signalfd_copyinfo(struct signalfd_siginfo __user *uinfo,
  72                             kernel_siginfo_t const *kinfo)
  73{
  74        struct signalfd_siginfo new;
  75
  76        BUILD_BUG_ON(sizeof(struct signalfd_siginfo) != 128);
  77
  78        /*
  79         * Unused members should be zero ...
  80         */
  81        memset(&new, 0, sizeof(new));
  82
  83        /*
  84         * If you change siginfo_t structure, please be sure
  85         * this code is fixed accordingly.
  86         */
  87        new.ssi_signo = kinfo->si_signo;
  88        new.ssi_errno = kinfo->si_errno;
  89        new.ssi_code  = kinfo->si_code;
  90        switch (siginfo_layout(kinfo->si_signo, kinfo->si_code)) {
  91        case SIL_KILL:
  92                new.ssi_pid = kinfo->si_pid;
  93                new.ssi_uid = kinfo->si_uid;
  94                break;
  95        case SIL_TIMER:
  96                new.ssi_tid = kinfo->si_tid;
  97                new.ssi_overrun = kinfo->si_overrun;
  98                new.ssi_ptr = (long) kinfo->si_ptr;
  99                new.ssi_int = kinfo->si_int;
 100                break;
 101        case SIL_POLL:
 102                new.ssi_band = kinfo->si_band;
 103                new.ssi_fd   = kinfo->si_fd;
 104                break;
 105        case SIL_FAULT_BNDERR:
 106        case SIL_FAULT_PKUERR:
 107        case SIL_FAULT_PERF_EVENT:
 108                /*
 109                 * Fall through to the SIL_FAULT case.  SIL_FAULT_BNDERR,
 110                 * SIL_FAULT_PKUERR, and SIL_FAULT_PERF_EVENT are only
 111                 * generated by faults that deliver them synchronously to
 112                 * userspace.  In case someone injects one of these signals
 113                 * and signalfd catches it treat it as SIL_FAULT.
 114                 */
 115        case SIL_FAULT:
 116                new.ssi_addr = (long) kinfo->si_addr;
 117                break;
 118        case SIL_FAULT_TRAPNO:
 119                new.ssi_addr = (long) kinfo->si_addr;
 120                new.ssi_trapno = kinfo->si_trapno;
 121                break;
 122        case SIL_FAULT_MCEERR:
 123                new.ssi_addr = (long) kinfo->si_addr;
 124                new.ssi_addr_lsb = (short) kinfo->si_addr_lsb;
 125                break;
 126        case SIL_CHLD:
 127                new.ssi_pid    = kinfo->si_pid;
 128                new.ssi_uid    = kinfo->si_uid;
 129                new.ssi_status = kinfo->si_status;
 130                new.ssi_utime  = kinfo->si_utime;
 131                new.ssi_stime  = kinfo->si_stime;
 132                break;
 133        case SIL_RT:
 134                /*
 135                 * This case catches also the signals queued by sigqueue().
 136                 */
 137                new.ssi_pid = kinfo->si_pid;
 138                new.ssi_uid = kinfo->si_uid;
 139                new.ssi_ptr = (long) kinfo->si_ptr;
 140                new.ssi_int = kinfo->si_int;
 141                break;
 142        case SIL_SYS:
 143                new.ssi_call_addr = (long) kinfo->si_call_addr;
 144                new.ssi_syscall   = kinfo->si_syscall;
 145                new.ssi_arch      = kinfo->si_arch;
 146                break;
 147        }
 148
 149        if (copy_to_user(uinfo, &new, sizeof(struct signalfd_siginfo)))
 150                return -EFAULT;
 151
 152        return sizeof(*uinfo);
 153}
 154
 155static ssize_t signalfd_dequeue(struct signalfd_ctx *ctx, kernel_siginfo_t *info,
 156                                int nonblock)
 157{
 158        enum pid_type type;
 159        ssize_t ret;
 160        DECLARE_WAITQUEUE(wait, current);
 161
 162        spin_lock_irq(&current->sighand->siglock);
 163        ret = dequeue_signal(current, &ctx->sigmask, info, &type);
 164        switch (ret) {
 165        case 0:
 166                if (!nonblock)
 167                        break;
 168                ret = -EAGAIN;
 169                fallthrough;
 170        default:
 171                spin_unlock_irq(&current->sighand->siglock);
 172                return ret;
 173        }
 174
 175        add_wait_queue(&current->sighand->signalfd_wqh, &wait);
 176        for (;;) {
 177                set_current_state(TASK_INTERRUPTIBLE);
 178                ret = dequeue_signal(current, &ctx->sigmask, info, &type);
 179                if (ret != 0)
 180                        break;
 181                if (signal_pending(current)) {
 182                        ret = -ERESTARTSYS;
 183                        break;
 184                }
 185                spin_unlock_irq(&current->sighand->siglock);
 186                schedule();
 187                spin_lock_irq(&current->sighand->siglock);
 188        }
 189        spin_unlock_irq(&current->sighand->siglock);
 190
 191        remove_wait_queue(&current->sighand->signalfd_wqh, &wait);
 192        __set_current_state(TASK_RUNNING);
 193
 194        return ret;
 195}
 196
 197/*
 198 * Returns a multiple of the size of a "struct signalfd_siginfo", or a negative
 199 * error code. The "count" parameter must be at least the size of a
 200 * "struct signalfd_siginfo".
 201 */
 202static ssize_t signalfd_read(struct file *file, char __user *buf, size_t count,
 203                             loff_t *ppos)
 204{
 205        struct signalfd_ctx *ctx = file->private_data;
 206        struct signalfd_siginfo __user *siginfo;
 207        int nonblock = file->f_flags & O_NONBLOCK;
 208        ssize_t ret, total = 0;
 209        kernel_siginfo_t info;
 210
 211        count /= sizeof(struct signalfd_siginfo);
 212        if (!count)
 213                return -EINVAL;
 214
 215        siginfo = (struct signalfd_siginfo __user *) buf;
 216        do {
 217                ret = signalfd_dequeue(ctx, &info, nonblock);
 218                if (unlikely(ret <= 0))
 219                        break;
 220                ret = signalfd_copyinfo(siginfo, &info);
 221                if (ret < 0)
 222                        break;
 223                siginfo++;
 224                total += ret;
 225                nonblock = 1;
 226        } while (--count);
 227
 228        return total ? total: ret;
 229}
 230
 231#ifdef CONFIG_PROC_FS
 232static void signalfd_show_fdinfo(struct seq_file *m, struct file *f)
 233{
 234        struct signalfd_ctx *ctx = f->private_data;
 235        sigset_t sigmask;
 236
 237        sigmask = ctx->sigmask;
 238        signotset(&sigmask);
 239        render_sigset_t(m, "sigmask:\t", &sigmask);
 240}
 241#endif
 242
 243static const struct file_operations signalfd_fops = {
 244#ifdef CONFIG_PROC_FS
 245        .show_fdinfo    = signalfd_show_fdinfo,
 246#endif
 247        .release        = signalfd_release,
 248        .poll           = signalfd_poll,
 249        .read           = signalfd_read,
 250        .llseek         = noop_llseek,
 251};
 252
 253static int do_signalfd4(int ufd, sigset_t *mask, int flags)
 254{
 255        struct signalfd_ctx *ctx;
 256
 257        /* Check the SFD_* constants for consistency.  */
 258        BUILD_BUG_ON(SFD_CLOEXEC != O_CLOEXEC);
 259        BUILD_BUG_ON(SFD_NONBLOCK != O_NONBLOCK);
 260
 261        if (flags & ~(SFD_CLOEXEC | SFD_NONBLOCK))
 262                return -EINVAL;
 263
 264        sigdelsetmask(mask, sigmask(SIGKILL) | sigmask(SIGSTOP));
 265        signotset(mask);
 266
 267        if (ufd == -1) {
 268                ctx = kmalloc(sizeof(*ctx), GFP_KERNEL);
 269                if (!ctx)
 270                        return -ENOMEM;
 271
 272                ctx->sigmask = *mask;
 273
 274                /*
 275                 * When we call this, the initialization must be complete, since
 276                 * anon_inode_getfd() will install the fd.
 277                 */
 278                ufd = anon_inode_getfd("[signalfd]", &signalfd_fops, ctx,
 279                                       O_RDWR | (flags & (O_CLOEXEC | O_NONBLOCK)));
 280                if (ufd < 0)
 281                        kfree(ctx);
 282        } else {
 283                struct fd f = fdget(ufd);
 284                if (!f.file)
 285                        return -EBADF;
 286                ctx = f.file->private_data;
 287                if (f.file->f_op != &signalfd_fops) {
 288                        fdput(f);
 289                        return -EINVAL;
 290                }
 291                spin_lock_irq(&current->sighand->siglock);
 292                ctx->sigmask = *mask;
 293                spin_unlock_irq(&current->sighand->siglock);
 294
 295                wake_up(&current->sighand->signalfd_wqh);
 296                fdput(f);
 297        }
 298
 299        return ufd;
 300}
 301
 302SYSCALL_DEFINE4(signalfd4, int, ufd, sigset_t __user *, user_mask,
 303                size_t, sizemask, int, flags)
 304{
 305        sigset_t mask;
 306
 307        if (sizemask != sizeof(sigset_t))
 308                return -EINVAL;
 309        if (copy_from_user(&mask, user_mask, sizeof(mask)))
 310                return -EFAULT;
 311        return do_signalfd4(ufd, &mask, flags);
 312}
 313
 314SYSCALL_DEFINE3(signalfd, int, ufd, sigset_t __user *, user_mask,
 315                size_t, sizemask)
 316{
 317        sigset_t mask;
 318
 319        if (sizemask != sizeof(sigset_t))
 320                return -EINVAL;
 321        if (copy_from_user(&mask, user_mask, sizeof(mask)))
 322                return -EFAULT;
 323        return do_signalfd4(ufd, &mask, 0);
 324}
 325
 326#ifdef CONFIG_COMPAT
 327static long do_compat_signalfd4(int ufd,
 328                        const compat_sigset_t __user *user_mask,
 329                        compat_size_t sigsetsize, int flags)
 330{
 331        sigset_t mask;
 332
 333        if (sigsetsize != sizeof(compat_sigset_t))
 334                return -EINVAL;
 335        if (get_compat_sigset(&mask, user_mask))
 336                return -EFAULT;
 337        return do_signalfd4(ufd, &mask, flags);
 338}
 339
 340COMPAT_SYSCALL_DEFINE4(signalfd4, int, ufd,
 341                     const compat_sigset_t __user *, user_mask,
 342                     compat_size_t, sigsetsize,
 343                     int, flags)
 344{
 345        return do_compat_signalfd4(ufd, user_mask, sigsetsize, flags);
 346}
 347
 348COMPAT_SYSCALL_DEFINE3(signalfd, int, ufd,
 349                     const compat_sigset_t __user *, user_mask,
 350                     compat_size_t, sigsetsize)
 351{
 352        return do_compat_signalfd4(ufd, user_mask, sigsetsize, 0);
 353}
 354#endif
 355