1. 12 Aug, 2021 1 commit
    • Maximilian Heyne's avatar
      xen/events: Fix race in set_evtchn_to_irq · 88ca2521
      Maximilian Heyne authored
      There is a TOCTOU issue in set_evtchn_to_irq. Rows in the evtchn_to_irq
      mapping are lazily allocated in this function. The check whether the row
      is already present and the row initialization is not synchronized. Two
      threads can at the same time allocate a new row for evtchn_to_irq and
      add the irq mapping to the their newly allocated row. One thread will
      overwrite what the other has set for evtchn_to_irq[row] and therefore
      the irq mapping is lost. This will trigger a BUG_ON later in
      bind_evtchn_to_cpu:
      
        INFO: pci 0000:1a:15.4: [1d0f:8061] type 00 class 0x010802
        INFO: nvme 0000:1a:12.1: enabling device (0000 -> 0002)
        INFO: nvme nvme77: 1/0/0 default/read/poll queues
        CRIT: kernel BUG at drivers/xen/events/events_base.c:427!
        WARN: invalid opcode: 0000 [#1] SMP NOPTI
        WARN: Workqueue: nvme-reset-wq nvme_reset_work [nvme]
        WARN: RIP: e030:bind_evtchn_to_cpu+0xc2/0xd0
        WARN: Call Trace:
        WARN:  set_affinity_irq+0x121/0x150
        WARN:  irq_do_set_affinity+0x37/0xe0
        WARN:  irq_setup_affinity+0xf6/0x170
        WARN:  irq_startup+0x64/0xe0
        WARN:  __setup_irq+0x69e/0x740
        WARN:  ? request_threaded_irq+0xad/0x160
        WARN:  request_threaded_irq+0xf5/0x160
        WARN:  ? nvme_timeout+0x2f0/0x2f0 [nvme]
        WARN:  pci_request_irq+0xa9/0xf0
        WARN:  ? pci_alloc_irq_vectors_affinity+0xbb/0x130
        WARN:  queue_request_irq+0x4c/0x70 [nvme]
        WARN:  nvme_reset_work+0x82d/0x1550 [nvme]
        WARN:  ? check_preempt_wakeup+0x14f/0x230
        WARN:  ? check_preempt_curr+0x29/0x80
        WARN:  ? nvme_irq_check+0x30/0x30 [nvme]
        WARN:  process_one_work+0x18e/0x3c0
        WARN:  worker_thread+0x30/0x3a0
        WARN:  ? process_one_work+0x3c0/0x3c0
        WARN:  kthread+0x113/0x130
        WARN:  ? kthread_park+0x90/0x90
        WARN:  ret_from_fork+0x3a/0x50
      
      This patch sets evtchn_to_irq rows via a cmpxchg operation so that they
      will be set only once. The row is now cleared before writing it to
      evtchn_to_irq in order to not create a race once the row is visible for
      other threads.
      
      While at it, do not require the page to be zeroed, because it will be
      overwritten with -1's in clear_evtchn_to_irq_row anyway.
      Signed-off-by: default avatarMaximilian Heyne <mheyne@amazon.de>
      Fixes: d0b075ff ("xen/events: Refactor evtchn_to_irq array to be dynamically allocated")
      Link: https://lore.kernel.org/r/20210812130930.127134-1-mheyne@amazon.deReviewed-by: default avatarBoris Ostrovsky <boris.ostrovsky@oracle.com>
      Signed-off-by: default avatarBoris Ostrovsky <boris.ostrovsky@oracle.com>
      88ca2521
  2. 21 Jul, 2021 1 commit
  3. 05 Jul, 2021 2 commits
  4. 27 Jun, 2021 2 commits
    • Linus Torvalds's avatar
      Linux 5.13 · 62fb9874
      Linus Torvalds authored
      62fb9874
    • Linus Torvalds's avatar
      Revert "signal: Allow tasks to cache one sigqueue struct" · b4b27b9e
      Linus Torvalds authored
      This reverts commits 4bad58eb (and
      399f8dd9, which tried to fix it).
      
      I do not believe these are correct, and I'm about to release 5.13, so am
      reverting them out of an abundance of caution.
      
      The locking is odd, and appears broken.
      
      On the allocation side (in __sigqueue_alloc()), the locking is somewhat
      straightforward: it depends on sighand->siglock.  Since one caller
      doesn't hold that lock, it further then tests 'sigqueue_flags' to avoid
      the case with no locks held.
      
      On the freeing side (in sigqueue_cache_or_free()), there is no locking
      at all, and the logic instead depends on 'current' being a single
      thread, and not able to race with itself.
      
      To make things more exciting, there's also the data race between freeing
      a signal and allocating one, which is handled by using WRITE_ONCE() and
      READ_ONCE(), and being mutually exclusive wrt the initial state (ie
      freeing will only free if the old state was NULL, while allocating will
      obviously only use the value if it was non-NULL, so only one or the
      other will actually act on the value).
      
      However, while the free->alloc paths do seem mutually exclusive thanks
      to just the data value dependency, it's not clear what the memory
      ordering constraints are on it.  Could writes from the previous
      allocation possibly be delayed and seen by the new allocation later,
      causing logical inconsistencies?
      
      So it's all very exciting and unusual.
      
      And in particular, it seems that the freeing side is incorrect in
      depending on "current" being single-threaded.  Yes, 'current' is a
      single thread, but in the presense of asynchronous events even a single
      thread can have data races.
      
      And such asynchronous events can and do happen, with interrupts causing
      signals to be flushed and thus free'd (for example - sending a
      SIGCONT/SIGSTOP can happen from interrupt context, and can flush
      previously queued process control signals).
      
      So regardless of all the other questions about the memory ordering and
      locking for this new cached allocation, the sigqueue_cache_or_free()
      assumptions seem to be fundamentally incorrect.
      
      It may be that people will show me the errors of my ways, and tell me
      why this is all safe after all.  We can reinstate it if so.  But my
      current belief is that the WRITE_ONCE() that sets the cached entry needs
      to be a smp_store_release(), and the READ_ONCE() that finds a cached
      entry needs to be a smp_load_acquire() to handle memory ordering
      correctly.
      
      And the sequence in sigqueue_cache_or_free() would need to either use a
      lock or at least be interrupt-safe some way (perhaps by using something
      like the percpu 'cmpxchg': it doesn't need to be SMP-safe, but like the
      percpu operations it needs to be interrupt-safe).
      
      Fixes: 399f8dd9 ("signal: Prevent sigqueue caching after task got released")
      Fixes: 4bad58eb ("signal: Allow tasks to cache one sigqueue struct")
      Cc: Thomas Gleixner <tglx@linutronix.de>
      Cc: Peter Zijlstra <peterz@infradead.org>
      Cc: Oleg Nesterov <oleg@redhat.com>
      Cc: Christian Brauner <christian.brauner@ubuntu.com>
      Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
      b4b27b9e
  5. 26 Jun, 2021 2 commits
  6. 25 Jun, 2021 32 commits