commit:     2751f9756a2c77cf0b05c2e3212dfbcc8d98cf5e
Author:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Fri Nov 12 14:36:50 2021 +0000
Commit:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Fri Nov 12 14:36:50 2021 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=2751f975

Linux patch 5.15.2

Signed-off-by: Mike Pagano <mpagano <AT> gentoo.org>

 0000_README             |    4 +
 1001_linux-5.15.2.patch | 1310 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 1314 insertions(+)

diff --git a/0000_README b/0000_README
index 23b2f2d0..dd0e8a67 100644
--- a/0000_README
+++ b/0000_README
@@ -47,6 +47,10 @@ Patch:  1000_linux-5.15.1.patch
 From:   http://www.kernel.org
 Desc:   Linux 5.15.1
 
+Patch:  1001_linux-5.15.2.patch
+From:   http://www.kernel.org
+Desc:   Linux 5.15.2
+
 Patch:  1500_XATTR_USER_PREFIX.patch
 From:   https://bugs.gentoo.org/show_bug.cgi?id=470644
 Desc:   Support for namespace user.pax.* on tmpfs.

diff --git a/1001_linux-5.15.2.patch b/1001_linux-5.15.2.patch
new file mode 100644
index 00000000..8f38f6d7
--- /dev/null
+++ b/1001_linux-5.15.2.patch
@@ -0,0 +1,1310 @@
+diff --git a/Documentation/dev-tools/kfence.rst 
b/Documentation/dev-tools/kfence.rst
+index 0fbe3308bf37f..48244d32780f6 100644
+--- a/Documentation/dev-tools/kfence.rst
++++ b/Documentation/dev-tools/kfence.rst
+@@ -231,10 +231,14 @@ Guarded allocations are set up based on the sample 
interval. After expiration
+ of the sample interval, the next allocation through the main allocator (SLAB 
or
+ SLUB) returns a guarded allocation from the KFENCE object pool (allocation
+ sizes up to PAGE_SIZE are supported). At this point, the timer is reset, and
+-the next allocation is set up after the expiration of the interval. To "gate" 
a
+-KFENCE allocation through the main allocator's fast-path without overhead,
+-KFENCE relies on static branches via the static keys infrastructure. The 
static
+-branch is toggled to redirect the allocation to KFENCE.
++the next allocation is set up after the expiration of the interval.
++
++When using ``CONFIG_KFENCE_STATIC_KEYS=y``, KFENCE allocations are "gated"
++through the main allocator's fast-path by relying on static branches via the
++static keys infrastructure. The static branch is toggled to redirect the
++allocation to KFENCE. Depending on sample interval, target workloads, and
++system architecture, this may perform better than the simple dynamic branch.
++Careful benchmarking is recommended.
+ 
+ KFENCE objects each reside on a dedicated page, at either the left or right
+ page boundaries selected at random. The pages to the left and right of the
+diff --git a/Makefile b/Makefile
+index ffcc7eadc44b8..14480187ac75d 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,7 +1,7 @@
+ # SPDX-License-Identifier: GPL-2.0
+ VERSION = 5
+ PATCHLEVEL = 15
+-SUBLEVEL = 1
++SUBLEVEL = 2
+ EXTRAVERSION =
+ NAME = Trick or Treat
+ 
+diff --git a/arch/x86/kvm/ioapic.c b/arch/x86/kvm/ioapic.c
+index 8c065da73f8e5..4e0f52660842b 100644
+--- a/arch/x86/kvm/ioapic.c
++++ b/arch/x86/kvm/ioapic.c
+@@ -96,7 +96,7 @@ static unsigned long ioapic_read_indirect(struct kvm_ioapic 
*ioapic,
+ static void rtc_irq_eoi_tracking_reset(struct kvm_ioapic *ioapic)
+ {
+       ioapic->rtc_status.pending_eoi = 0;
+-      bitmap_zero(ioapic->rtc_status.dest_map.map, KVM_MAX_VCPU_ID + 1);
++      bitmap_zero(ioapic->rtc_status.dest_map.map, KVM_MAX_VCPU_ID);
+ }
+ 
+ static void kvm_rtc_eoi_tracking_restore_all(struct kvm_ioapic *ioapic);
+diff --git a/arch/x86/kvm/ioapic.h b/arch/x86/kvm/ioapic.h
+index bbd4a5d18b5dc..27e61ff3ac3e8 100644
+--- a/arch/x86/kvm/ioapic.h
++++ b/arch/x86/kvm/ioapic.h
+@@ -39,13 +39,13 @@ struct kvm_vcpu;
+ 
+ struct dest_map {
+       /* vcpu bitmap where IRQ has been sent */
+-      DECLARE_BITMAP(map, KVM_MAX_VCPU_ID + 1);
++      DECLARE_BITMAP(map, KVM_MAX_VCPU_ID);
+ 
+       /*
+        * Vector sent to a given vcpu, only valid when
+        * the vcpu's bit in map is set
+        */
+-      u8 vectors[KVM_MAX_VCPU_ID + 1];
++      u8 vectors[KVM_MAX_VCPU_ID];
+ };
+ 
+ 
+diff --git a/arch/x86/kvm/mmu/spte.h b/arch/x86/kvm/mmu/spte.h
+index eb7b227fc6cfe..31d6456d8ac33 100644
+--- a/arch/x86/kvm/mmu/spte.h
++++ b/arch/x86/kvm/mmu/spte.h
+@@ -310,12 +310,7 @@ static inline bool __is_bad_mt_xwr(struct 
rsvd_bits_validate *rsvd_check,
+ static __always_inline bool is_rsvd_spte(struct rsvd_bits_validate 
*rsvd_check,
+                                        u64 spte, int level)
+ {
+-      /*
+-       * Use a bitwise-OR instead of a logical-OR to aggregate the reserved
+-       * bits and EPT's invalid memtype/XWR checks to avoid an extra Jcc
+-       * (this is extremely unlikely to be short-circuited as true).
+-       */
+-      return __is_bad_mt_xwr(rsvd_check, spte) |
++      return __is_bad_mt_xwr(rsvd_check, spte) ||
+              __is_rsvd_bits_set(rsvd_check, spte, level);
+ }
+ 
+diff --git a/drivers/android/binder.c b/drivers/android/binder.c
+index 9edacc8b97688..49fb74196d02f 100644
+--- a/drivers/android/binder.c
++++ b/drivers/android/binder.c
+@@ -1870,7 +1870,7 @@ static void binder_transaction_buffer_release(struct 
binder_proc *proc,
+               binder_dec_node(buffer->target_node, 1, 0);
+ 
+       off_start_offset = ALIGN(buffer->data_size, sizeof(void *));
+-      off_end_offset = is_failure ? failed_at :
++      off_end_offset = is_failure && failed_at ? failed_at :
+                               off_start_offset + buffer->offsets_size;
+       for (buffer_offset = off_start_offset; buffer_offset < off_end_offset;
+            buffer_offset += sizeof(binder_size_t)) {
+@@ -1956,9 +1956,8 @@ static void binder_transaction_buffer_release(struct 
binder_proc *proc,
+                       binder_size_t fd_buf_size;
+                       binder_size_t num_valid;
+ 
+-                      if (proc->tsk != current->group_leader) {
++                      if (is_failure) {
+                               /*
+-                               * Nothing to do if running in sender context
+                                * The fd fixups have not been applied so no
+                                * fds need to be closed.
+                                */
+@@ -2056,7 +2055,7 @@ static int binder_translate_binder(struct 
flat_binder_object *fp,
+               ret = -EINVAL;
+               goto done;
+       }
+-      if (security_binder_transfer_binder(proc->tsk, target_proc->tsk)) {
++      if (security_binder_transfer_binder(proc->cred, target_proc->cred)) {
+               ret = -EPERM;
+               goto done;
+       }
+@@ -2102,7 +2101,7 @@ static int binder_translate_handle(struct 
flat_binder_object *fp,
+                                 proc->pid, thread->pid, fp->handle);
+               return -EINVAL;
+       }
+-      if (security_binder_transfer_binder(proc->tsk, target_proc->tsk)) {
++      if (security_binder_transfer_binder(proc->cred, target_proc->cred)) {
+               ret = -EPERM;
+               goto done;
+       }
+@@ -2190,7 +2189,7 @@ static int binder_translate_fd(u32 fd, binder_size_t 
fd_offset,
+               ret = -EBADF;
+               goto err_fget;
+       }
+-      ret = security_binder_transfer_file(proc->tsk, target_proc->tsk, file);
++      ret = security_binder_transfer_file(proc->cred, target_proc->cred, 
file);
+       if (ret < 0) {
+               ret = -EPERM;
+               goto err_security;
+@@ -2595,8 +2594,8 @@ static void binder_transaction(struct binder_proc *proc,
+                       return_error_line = __LINE__;
+                       goto err_invalid_target_handle;
+               }
+-              if (security_binder_transaction(proc->tsk,
+-                                              target_proc->tsk) < 0) {
++              if (security_binder_transaction(proc->cred,
++                                              target_proc->cred) < 0) {
+                       return_error = BR_FAILED_REPLY;
+                       return_error_param = -EPERM;
+                       return_error_line = __LINE__;
+@@ -2711,7 +2710,7 @@ static void binder_transaction(struct binder_proc *proc,
+               t->from = thread;
+       else
+               t->from = NULL;
+-      t->sender_euid = task_euid(proc->tsk);
++      t->sender_euid = proc->cred->euid;
+       t->to_proc = target_proc;
+       t->to_thread = target_thread;
+       t->code = tr->code;
+@@ -2722,16 +2721,7 @@ static void binder_transaction(struct binder_proc *proc,
+               u32 secid;
+               size_t added_size;
+ 
+-              /*
+-               * Arguably this should be the task's subjective LSM secid but
+-               * we can't reliably access the subjective creds of a task
+-               * other than our own so we must use the objective creds, which
+-               * are safe to access.  The downside is that if a task is
+-               * temporarily overriding it's creds it will not be reflected
+-               * here; however, it isn't clear that binder would handle that
+-               * case well anyway.
+-               */
+-              security_task_getsecid_obj(proc->tsk, &secid);
++              security_cred_getsecid(proc->cred, &secid);
+               ret = security_secid_to_secctx(secid, &secctx, &secctx_sz);
+               if (ret) {
+                       return_error = BR_FAILED_REPLY;
+@@ -3185,6 +3175,7 @@ err_invalid_target_handle:
+  * binder_free_buf() - free the specified buffer
+  * @proc:     binder proc that owns buffer
+  * @buffer:   buffer to be freed
++ * @is_failure:       failed to send transaction
+  *
+  * If buffer for an async transaction, enqueue the next async
+  * transaction from the node.
+@@ -3194,7 +3185,7 @@ err_invalid_target_handle:
+ static void
+ binder_free_buf(struct binder_proc *proc,
+               struct binder_thread *thread,
+-              struct binder_buffer *buffer)
++              struct binder_buffer *buffer, bool is_failure)
+ {
+       binder_inner_proc_lock(proc);
+       if (buffer->transaction) {
+@@ -3222,7 +3213,7 @@ binder_free_buf(struct binder_proc *proc,
+               binder_node_inner_unlock(buf_node);
+       }
+       trace_binder_transaction_buffer_release(buffer);
+-      binder_transaction_buffer_release(proc, thread, buffer, 0, false);
++      binder_transaction_buffer_release(proc, thread, buffer, 0, is_failure);
+       binder_alloc_free_buf(&proc->alloc, buffer);
+ }
+ 
+@@ -3424,7 +3415,7 @@ static int binder_thread_write(struct binder_proc *proc,
+                                    proc->pid, thread->pid, (u64)data_ptr,
+                                    buffer->debug_id,
+                                    buffer->transaction ? "active" : 
"finished");
+-                      binder_free_buf(proc, thread, buffer);
++                      binder_free_buf(proc, thread, buffer, false);
+                       break;
+               }
+ 
+@@ -4117,7 +4108,7 @@ retry:
+                       buffer->transaction = NULL;
+                       binder_cleanup_transaction(t, "fd fixups failed",
+                                                  BR_FAILED_REPLY);
+-                      binder_free_buf(proc, thread, buffer);
++                      binder_free_buf(proc, thread, buffer, true);
+                       binder_debug(BINDER_DEBUG_FAILED_TRANSACTION,
+                                    "%d:%d %stransaction %d fd fixups failed 
%d/%d, line %d\n",
+                                    proc->pid, thread->pid,
+@@ -4353,6 +4344,7 @@ static void binder_free_proc(struct binder_proc *proc)
+       }
+       binder_alloc_deferred_release(&proc->alloc);
+       put_task_struct(proc->tsk);
++      put_cred(proc->cred);
+       binder_stats_deleted(BINDER_STAT_PROC);
+       kfree(proc);
+ }
+@@ -4564,7 +4556,7 @@ static int binder_ioctl_set_ctx_mgr(struct file *filp,
+               ret = -EBUSY;
+               goto out;
+       }
+-      ret = security_binder_set_context_mgr(proc->tsk);
++      ret = security_binder_set_context_mgr(proc->cred);
+       if (ret < 0)
+               goto out;
+       if (uid_valid(context->binder_context_mgr_uid)) {
+@@ -5055,6 +5047,7 @@ static int binder_open(struct inode *nodp, struct file 
*filp)
+       spin_lock_init(&proc->outer_lock);
+       get_task_struct(current->group_leader);
+       proc->tsk = current->group_leader;
++      proc->cred = get_cred(filp->f_cred);
+       INIT_LIST_HEAD(&proc->todo);
+       init_waitqueue_head(&proc->freeze_wait);
+       proc->default_priority = task_nice(current);
+diff --git a/drivers/android/binder_internal.h 
b/drivers/android/binder_internal.h
+index 402c4d4362a83..d6b6b8cb73465 100644
+--- a/drivers/android/binder_internal.h
++++ b/drivers/android/binder_internal.h
+@@ -364,6 +364,9 @@ struct binder_ref {
+  *                        (invariant after initialized)
+  * @tsk                   task_struct for group_leader of process
+  *                        (invariant after initialized)
++ * @cred                  struct cred associated with the `struct file`
++ *                        in binder_open()
++ *                        (invariant after initialized)
+  * @deferred_work_node:   element for binder_deferred_list
+  *                        (protected by binder_deferred_lock)
+  * @deferred_work:        bitmap of deferred work to perform
+@@ -426,6 +429,7 @@ struct binder_proc {
+       struct list_head waiting_threads;
+       int pid;
+       struct task_struct *tsk;
++      const struct cred *cred;
+       struct hlist_node deferred_work_node;
+       int deferred_work;
+       int outstanding_txns;
+diff --git a/drivers/comedi/drivers/dt9812.c b/drivers/comedi/drivers/dt9812.c
+index 634f57730c1e0..704b04d2980d3 100644
+--- a/drivers/comedi/drivers/dt9812.c
++++ b/drivers/comedi/drivers/dt9812.c
+@@ -32,6 +32,7 @@
+ #include <linux/kernel.h>
+ #include <linux/module.h>
+ #include <linux/errno.h>
++#include <linux/slab.h>
+ #include <linux/uaccess.h>
+ 
+ #include "../comedi_usb.h"
+@@ -237,22 +238,42 @@ static int dt9812_read_info(struct comedi_device *dev,
+ {
+       struct usb_device *usb = comedi_to_usb_dev(dev);
+       struct dt9812_private *devpriv = dev->private;
+-      struct dt9812_usb_cmd cmd;
++      struct dt9812_usb_cmd *cmd;
++      size_t tbuf_size;
+       int count, ret;
++      void *tbuf;
+ 
+-      cmd.cmd = cpu_to_le32(DT9812_R_FLASH_DATA);
+-      cmd.u.flash_data_info.address =
++      tbuf_size = max(sizeof(*cmd), buf_size);
++
++      tbuf = kzalloc(tbuf_size, GFP_KERNEL);
++      if (!tbuf)
++              return -ENOMEM;
++
++      cmd = tbuf;
++
++      cmd->cmd = cpu_to_le32(DT9812_R_FLASH_DATA);
++      cmd->u.flash_data_info.address =
+           cpu_to_le16(DT9812_DIAGS_BOARD_INFO_ADDR + offset);
+-      cmd.u.flash_data_info.numbytes = cpu_to_le16(buf_size);
++      cmd->u.flash_data_info.numbytes = cpu_to_le16(buf_size);
+ 
+       /* DT9812 only responds to 32 byte writes!! */
+       ret = usb_bulk_msg(usb, usb_sndbulkpipe(usb, devpriv->cmd_wr.addr),
+-                         &cmd, 32, &count, DT9812_USB_TIMEOUT);
++                         cmd, sizeof(*cmd), &count, DT9812_USB_TIMEOUT);
+       if (ret)
+-              return ret;
++              goto out;
++
++      ret = usb_bulk_msg(usb, usb_rcvbulkpipe(usb, devpriv->cmd_rd.addr),
++                         tbuf, buf_size, &count, DT9812_USB_TIMEOUT);
++      if (!ret) {
++              if (count == buf_size)
++                      memcpy(buf, tbuf, buf_size);
++              else
++                      ret = -EREMOTEIO;
++      }
++out:
++      kfree(tbuf);
+ 
+-      return usb_bulk_msg(usb, usb_rcvbulkpipe(usb, devpriv->cmd_rd.addr),
+-                          buf, buf_size, &count, DT9812_USB_TIMEOUT);
++      return ret;
+ }
+ 
+ static int dt9812_read_multiple_registers(struct comedi_device *dev,
+@@ -261,22 +282,42 @@ static int dt9812_read_multiple_registers(struct 
comedi_device *dev,
+ {
+       struct usb_device *usb = comedi_to_usb_dev(dev);
+       struct dt9812_private *devpriv = dev->private;
+-      struct dt9812_usb_cmd cmd;
++      struct dt9812_usb_cmd *cmd;
+       int i, count, ret;
++      size_t buf_size;
++      void *buf;
+ 
+-      cmd.cmd = cpu_to_le32(DT9812_R_MULTI_BYTE_REG);
+-      cmd.u.read_multi_info.count = reg_count;
++      buf_size = max_t(size_t, sizeof(*cmd), reg_count);
++
++      buf = kzalloc(buf_size, GFP_KERNEL);
++      if (!buf)
++              return -ENOMEM;
++
++      cmd = buf;
++
++      cmd->cmd = cpu_to_le32(DT9812_R_MULTI_BYTE_REG);
++      cmd->u.read_multi_info.count = reg_count;
+       for (i = 0; i < reg_count; i++)
+-              cmd.u.read_multi_info.address[i] = address[i];
++              cmd->u.read_multi_info.address[i] = address[i];
+ 
+       /* DT9812 only responds to 32 byte writes!! */
+       ret = usb_bulk_msg(usb, usb_sndbulkpipe(usb, devpriv->cmd_wr.addr),
+-                         &cmd, 32, &count, DT9812_USB_TIMEOUT);
++                         cmd, sizeof(*cmd), &count, DT9812_USB_TIMEOUT);
+       if (ret)
+-              return ret;
++              goto out;
++
++      ret = usb_bulk_msg(usb, usb_rcvbulkpipe(usb, devpriv->cmd_rd.addr),
++                         buf, reg_count, &count, DT9812_USB_TIMEOUT);
++      if (!ret) {
++              if (count == reg_count)
++                      memcpy(value, buf, reg_count);
++              else
++                      ret = -EREMOTEIO;
++      }
++out:
++      kfree(buf);
+ 
+-      return usb_bulk_msg(usb, usb_rcvbulkpipe(usb, devpriv->cmd_rd.addr),
+-                          value, reg_count, &count, DT9812_USB_TIMEOUT);
++      return ret;
+ }
+ 
+ static int dt9812_write_multiple_registers(struct comedi_device *dev,
+@@ -285,19 +326,27 @@ static int dt9812_write_multiple_registers(struct 
comedi_device *dev,
+ {
+       struct usb_device *usb = comedi_to_usb_dev(dev);
+       struct dt9812_private *devpriv = dev->private;
+-      struct dt9812_usb_cmd cmd;
++      struct dt9812_usb_cmd *cmd;
+       int i, count;
++      int ret;
++
++      cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
++      if (!cmd)
++              return -ENOMEM;
+ 
+-      cmd.cmd = cpu_to_le32(DT9812_W_MULTI_BYTE_REG);
+-      cmd.u.read_multi_info.count = reg_count;
++      cmd->cmd = cpu_to_le32(DT9812_W_MULTI_BYTE_REG);
++      cmd->u.read_multi_info.count = reg_count;
+       for (i = 0; i < reg_count; i++) {
+-              cmd.u.write_multi_info.write[i].address = address[i];
+-              cmd.u.write_multi_info.write[i].value = value[i];
++              cmd->u.write_multi_info.write[i].address = address[i];
++              cmd->u.write_multi_info.write[i].value = value[i];
+       }
+ 
+       /* DT9812 only responds to 32 byte writes!! */
+-      return usb_bulk_msg(usb, usb_sndbulkpipe(usb, devpriv->cmd_wr.addr),
+-                          &cmd, 32, &count, DT9812_USB_TIMEOUT);
++      ret = usb_bulk_msg(usb, usb_sndbulkpipe(usb, devpriv->cmd_wr.addr),
++                         cmd, sizeof(*cmd), &count, DT9812_USB_TIMEOUT);
++      kfree(cmd);
++
++      return ret;
+ }
+ 
+ static int dt9812_rmw_multiple_registers(struct comedi_device *dev,
+@@ -306,17 +355,25 @@ static int dt9812_rmw_multiple_registers(struct 
comedi_device *dev,
+ {
+       struct usb_device *usb = comedi_to_usb_dev(dev);
+       struct dt9812_private *devpriv = dev->private;
+-      struct dt9812_usb_cmd cmd;
++      struct dt9812_usb_cmd *cmd;
+       int i, count;
++      int ret;
++
++      cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
++      if (!cmd)
++              return -ENOMEM;
+ 
+-      cmd.cmd = cpu_to_le32(DT9812_RMW_MULTI_BYTE_REG);
+-      cmd.u.rmw_multi_info.count = reg_count;
++      cmd->cmd = cpu_to_le32(DT9812_RMW_MULTI_BYTE_REG);
++      cmd->u.rmw_multi_info.count = reg_count;
+       for (i = 0; i < reg_count; i++)
+-              cmd.u.rmw_multi_info.rmw[i] = rmw[i];
++              cmd->u.rmw_multi_info.rmw[i] = rmw[i];
+ 
+       /* DT9812 only responds to 32 byte writes!! */
+-      return usb_bulk_msg(usb, usb_sndbulkpipe(usb, devpriv->cmd_wr.addr),
+-                          &cmd, 32, &count, DT9812_USB_TIMEOUT);
++      ret = usb_bulk_msg(usb, usb_sndbulkpipe(usb, devpriv->cmd_wr.addr),
++                         cmd, sizeof(*cmd), &count, DT9812_USB_TIMEOUT);
++      kfree(cmd);
++
++      return ret;
+ }
+ 
+ static int dt9812_digital_in(struct comedi_device *dev, u8 *bits)
+diff --git a/drivers/comedi/drivers/ni_usb6501.c 
b/drivers/comedi/drivers/ni_usb6501.c
+index 5b6d9d783b2f7..c42987b74b1dc 100644
+--- a/drivers/comedi/drivers/ni_usb6501.c
++++ b/drivers/comedi/drivers/ni_usb6501.c
+@@ -144,6 +144,10 @@ static const u8 READ_COUNTER_RESPONSE[]   = {0x00, 0x01, 
0x00, 0x10,
+                                          0x00, 0x00, 0x00, 0x02,
+                                          0x00, 0x00, 0x00, 0x00};
+ 
++/* Largest supported packets */
++static const size_t TX_MAX_SIZE       = sizeof(SET_PORT_DIR_REQUEST);
++static const size_t RX_MAX_SIZE       = sizeof(READ_PORT_RESPONSE);
++
+ enum commands {
+       READ_PORT,
+       WRITE_PORT,
+@@ -501,6 +505,12 @@ static int ni6501_find_endpoints(struct comedi_device 
*dev)
+       if (!devpriv->ep_rx || !devpriv->ep_tx)
+               return -ENODEV;
+ 
++      if (usb_endpoint_maxp(devpriv->ep_rx) < RX_MAX_SIZE)
++              return -ENODEV;
++
++      if (usb_endpoint_maxp(devpriv->ep_tx) < TX_MAX_SIZE)
++              return -ENODEV;
++
+       return 0;
+ }
+ 
+diff --git a/drivers/comedi/drivers/vmk80xx.c 
b/drivers/comedi/drivers/vmk80xx.c
+index 9f920819cd742..4b00a9ea611ab 100644
+--- a/drivers/comedi/drivers/vmk80xx.c
++++ b/drivers/comedi/drivers/vmk80xx.c
+@@ -90,6 +90,9 @@ enum {
+ #define IC3_VERSION           BIT(0)
+ #define IC6_VERSION           BIT(1)
+ 
++#define MIN_BUF_SIZE          64
++#define PACKET_TIMEOUT                10000   /* ms */
++
+ enum vmk80xx_model {
+       VMK8055_MODEL,
+       VMK8061_MODEL
+@@ -157,22 +160,21 @@ static void vmk80xx_do_bulk_msg(struct comedi_device 
*dev)
+       __u8 rx_addr;
+       unsigned int tx_pipe;
+       unsigned int rx_pipe;
+-      size_t size;
++      size_t tx_size;
++      size_t rx_size;
+ 
+       tx_addr = devpriv->ep_tx->bEndpointAddress;
+       rx_addr = devpriv->ep_rx->bEndpointAddress;
+       tx_pipe = usb_sndbulkpipe(usb, tx_addr);
+       rx_pipe = usb_rcvbulkpipe(usb, rx_addr);
++      tx_size = usb_endpoint_maxp(devpriv->ep_tx);
++      rx_size = usb_endpoint_maxp(devpriv->ep_rx);
+ 
+-      /*
+-       * The max packet size attributes of the K8061
+-       * input/output endpoints are identical
+-       */
+-      size = usb_endpoint_maxp(devpriv->ep_tx);
++      usb_bulk_msg(usb, tx_pipe, devpriv->usb_tx_buf, tx_size, NULL,
++                   PACKET_TIMEOUT);
+ 
+-      usb_bulk_msg(usb, tx_pipe, devpriv->usb_tx_buf,
+-                   size, NULL, devpriv->ep_tx->bInterval);
+-      usb_bulk_msg(usb, rx_pipe, devpriv->usb_rx_buf, size, NULL, HZ * 10);
++      usb_bulk_msg(usb, rx_pipe, devpriv->usb_rx_buf, rx_size, NULL,
++                   PACKET_TIMEOUT);
+ }
+ 
+ static int vmk80xx_read_packet(struct comedi_device *dev)
+@@ -191,7 +193,7 @@ static int vmk80xx_read_packet(struct comedi_device *dev)
+       pipe = usb_rcvintpipe(usb, ep->bEndpointAddress);
+       return usb_interrupt_msg(usb, pipe, devpriv->usb_rx_buf,
+                                usb_endpoint_maxp(ep), NULL,
+-                               HZ * 10);
++                               PACKET_TIMEOUT);
+ }
+ 
+ static int vmk80xx_write_packet(struct comedi_device *dev, int cmd)
+@@ -212,7 +214,7 @@ static int vmk80xx_write_packet(struct comedi_device *dev, 
int cmd)
+       pipe = usb_sndintpipe(usb, ep->bEndpointAddress);
+       return usb_interrupt_msg(usb, pipe, devpriv->usb_tx_buf,
+                                usb_endpoint_maxp(ep), NULL,
+-                               HZ * 10);
++                               PACKET_TIMEOUT);
+ }
+ 
+ static int vmk80xx_reset_device(struct comedi_device *dev)
+@@ -678,12 +680,12 @@ static int vmk80xx_alloc_usb_buffers(struct 
comedi_device *dev)
+       struct vmk80xx_private *devpriv = dev->private;
+       size_t size;
+ 
+-      size = usb_endpoint_maxp(devpriv->ep_rx);
++      size = max(usb_endpoint_maxp(devpriv->ep_rx), MIN_BUF_SIZE);
+       devpriv->usb_rx_buf = kzalloc(size, GFP_KERNEL);
+       if (!devpriv->usb_rx_buf)
+               return -ENOMEM;
+ 
+-      size = usb_endpoint_maxp(devpriv->ep_tx);
++      size = max(usb_endpoint_maxp(devpriv->ep_rx), MIN_BUF_SIZE);
+       devpriv->usb_tx_buf = kzalloc(size, GFP_KERNEL);
+       if (!devpriv->usb_tx_buf)
+               return -ENOMEM;
+diff --git a/drivers/net/wireless/rsi/rsi_91x_usb.c 
b/drivers/net/wireless/rsi/rsi_91x_usb.c
+index 416976f098882..e97f92915ed98 100644
+--- a/drivers/net/wireless/rsi/rsi_91x_usb.c
++++ b/drivers/net/wireless/rsi/rsi_91x_usb.c
+@@ -61,7 +61,7 @@ static int rsi_usb_card_write(struct rsi_hw *adapter,
+                             (void *)seg,
+                             (int)len,
+                             &transfer,
+-                            HZ * 5);
++                            USB_CTRL_SET_TIMEOUT);
+ 
+       if (status < 0) {
+               rsi_dbg(ERR_ZONE,
+diff --git a/drivers/staging/media/ipu3/ipu3-css-fw.c 
b/drivers/staging/media/ipu3/ipu3-css-fw.c
+index 45aff76198e2c..981693eed8155 100644
+--- a/drivers/staging/media/ipu3/ipu3-css-fw.c
++++ b/drivers/staging/media/ipu3/ipu3-css-fw.c
+@@ -124,12 +124,11 @@ int imgu_css_fw_init(struct imgu_css *css)
+       /* Check and display fw header info */
+ 
+       css->fwp = (struct imgu_fw_header *)css->fw->data;
+-      if (css->fw->size < sizeof(struct imgu_fw_header *) ||
++      if (css->fw->size < struct_size(css->fwp, binary_header, 1) ||
+           css->fwp->file_header.h_size != sizeof(struct imgu_fw_bi_file_h))
+               goto bad_fw;
+-      if (sizeof(struct imgu_fw_bi_file_h) +
+-          css->fwp->file_header.binary_nr * sizeof(struct imgu_fw_info) >
+-          css->fw->size)
++      if (struct_size(css->fwp, binary_header,
++                      css->fwp->file_header.binary_nr) > css->fw->size)
+               goto bad_fw;
+ 
+       dev_info(dev, "loaded firmware version %.64s, %u binaries, %zu bytes\n",
+diff --git a/drivers/staging/media/ipu3/ipu3-css-fw.h 
b/drivers/staging/media/ipu3/ipu3-css-fw.h
+index 3c078f15a2959..c0bc57fd678a7 100644
+--- a/drivers/staging/media/ipu3/ipu3-css-fw.h
++++ b/drivers/staging/media/ipu3/ipu3-css-fw.h
+@@ -171,7 +171,7 @@ struct imgu_fw_bi_file_h {
+ 
+ struct imgu_fw_header {
+       struct imgu_fw_bi_file_h file_header;
+-      struct imgu_fw_info binary_header[1];   /* binary_nr items */
++      struct imgu_fw_info binary_header[];    /* binary_nr items */
+ };
+ 
+ /******************* Firmware functions *******************/
+diff --git a/drivers/staging/r8188eu/os_dep/ioctl_linux.c 
b/drivers/staging/r8188eu/os_dep/ioctl_linux.c
+index 1fd3750760018..013c322b98a2d 100644
+--- a/drivers/staging/r8188eu/os_dep/ioctl_linux.c
++++ b/drivers/staging/r8188eu/os_dep/ioctl_linux.c
+@@ -1978,7 +1978,7 @@ static int rtw_wx_set_enc_ext(struct net_device *dev,
+       struct ieee_param *param = NULL;
+       struct iw_point *pencoding = &wrqu->encoding;
+       struct iw_encode_ext *pext = (struct iw_encode_ext *)extra;
+-      int ret = 0;
++      int ret = -1;
+ 
+       param_len = sizeof(struct ieee_param) + pext->key_len;
+       param = kzalloc(param_len, GFP_KERNEL);
+@@ -2004,7 +2004,7 @@ static int rtw_wx_set_enc_ext(struct net_device *dev,
+               alg_name = "CCMP";
+               break;
+       default:
+-              return -1;
++              goto out;
+       }
+ 
+       strncpy((char *)param->u.crypt.alg, alg_name, IEEE_CRYPT_ALG_NAME_LEN);
+@@ -2031,6 +2031,7 @@ static int rtw_wx_set_enc_ext(struct net_device *dev,
+ 
+       ret =  wpa_set_encryption(dev, param, param_len);
+ 
++out:
+       kfree(param);
+       return ret;
+ }
+diff --git a/drivers/staging/rtl8192u/r8192U_core.c 
b/drivers/staging/rtl8192u/r8192U_core.c
+index b6698656fc014..cf5cfee2936fd 100644
+--- a/drivers/staging/rtl8192u/r8192U_core.c
++++ b/drivers/staging/rtl8192u/r8192U_core.c
+@@ -229,7 +229,7 @@ int write_nic_byte_E(struct net_device *dev, int indx, u8 
data)
+ 
+       status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
+                                RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE,
+-                               indx | 0xfe00, 0, usbdata, 1, HZ / 2);
++                               indx | 0xfe00, 0, usbdata, 1, 500);
+       kfree(usbdata);
+ 
+       if (status < 0) {
+@@ -251,7 +251,7 @@ int read_nic_byte_E(struct net_device *dev, int indx, u8 
*data)
+ 
+       status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
+                                RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
+-                               indx | 0xfe00, 0, usbdata, 1, HZ / 2);
++                               indx | 0xfe00, 0, usbdata, 1, 500);
+       *data = *usbdata;
+       kfree(usbdata);
+ 
+@@ -279,7 +279,7 @@ int write_nic_byte(struct net_device *dev, int indx, u8 
data)
+       status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
+                                RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE,
+                                (indx & 0xff) | 0xff00, (indx >> 8) & 0x0f,
+-                               usbdata, 1, HZ / 2);
++                               usbdata, 1, 500);
+       kfree(usbdata);
+ 
+       if (status < 0) {
+@@ -305,7 +305,7 @@ int write_nic_word(struct net_device *dev, int indx, u16 
data)
+       status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
+                                RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE,
+                                (indx & 0xff) | 0xff00, (indx >> 8) & 0x0f,
+-                               usbdata, 2, HZ / 2);
++                               usbdata, 2, 500);
+       kfree(usbdata);
+ 
+       if (status < 0) {
+@@ -331,7 +331,7 @@ int write_nic_dword(struct net_device *dev, int indx, u32 
data)
+       status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
+                                RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE,
+                                (indx & 0xff) | 0xff00, (indx >> 8) & 0x0f,
+-                               usbdata, 4, HZ / 2);
++                               usbdata, 4, 500);
+       kfree(usbdata);
+ 
+       if (status < 0) {
+@@ -355,7 +355,7 @@ int read_nic_byte(struct net_device *dev, int indx, u8 
*data)
+       status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
+                                RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
+                                (indx & 0xff) | 0xff00, (indx >> 8) & 0x0f,
+-                               usbdata, 1, HZ / 2);
++                               usbdata, 1, 500);
+       *data = *usbdata;
+       kfree(usbdata);
+ 
+@@ -380,7 +380,7 @@ int read_nic_word(struct net_device *dev, int indx, u16 
*data)
+       status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
+                                RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
+                                (indx & 0xff) | 0xff00, (indx >> 8) & 0x0f,
+-                               usbdata, 2, HZ / 2);
++                               usbdata, 2, 500);
+       *data = *usbdata;
+       kfree(usbdata);
+ 
+@@ -404,7 +404,7 @@ static int read_nic_word_E(struct net_device *dev, int 
indx, u16 *data)
+ 
+       status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
+                                RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
+-                               indx | 0xfe00, 0, usbdata, 2, HZ / 2);
++                               indx | 0xfe00, 0, usbdata, 2, 500);
+       *data = *usbdata;
+       kfree(usbdata);
+ 
+@@ -430,7 +430,7 @@ int read_nic_dword(struct net_device *dev, int indx, u32 
*data)
+       status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
+                                RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
+                                (indx & 0xff) | 0xff00, (indx >> 8) & 0x0f,
+-                               usbdata, 4, HZ / 2);
++                               usbdata, 4, 500);
+       *data = *usbdata;
+       kfree(usbdata);
+ 
+diff --git a/drivers/staging/rtl8712/usb_intf.c 
b/drivers/staging/rtl8712/usb_intf.c
+index 505ebeb643dc2..cae04272deffe 100644
+--- a/drivers/staging/rtl8712/usb_intf.c
++++ b/drivers/staging/rtl8712/usb_intf.c
+@@ -595,12 +595,12 @@ static void r871xu_dev_remove(struct usb_interface 
*pusb_intf)
+ 
+       /* never exit with a firmware callback pending */
+       wait_for_completion(&padapter->rtl8712_fw_ready);
++      if (pnetdev->reg_state != NETREG_UNINITIALIZED)
++              unregister_netdev(pnetdev); /* will call netdev_close() */
+       usb_set_intfdata(pusb_intf, NULL);
+       release_firmware(padapter->fw);
+       if (drvpriv.drv_registered)
+               padapter->surprise_removed = true;
+-      if (pnetdev->reg_state != NETREG_UNINITIALIZED)
+-              unregister_netdev(pnetdev); /* will call netdev_close() */
+       r8712_flush_rwctrl_works(padapter);
+       r8712_flush_led_works(padapter);
+       udelay(1);
+diff --git a/drivers/staging/rtl8712/usb_ops_linux.c 
b/drivers/staging/rtl8712/usb_ops_linux.c
+index 655497cead122..f984a5ab2c6ff 100644
+--- a/drivers/staging/rtl8712/usb_ops_linux.c
++++ b/drivers/staging/rtl8712/usb_ops_linux.c
+@@ -494,7 +494,7 @@ int r8712_usbctrl_vendorreq(struct intf_priv *pintfpriv, 
u8 request, u16 value,
+               memcpy(pIo_buf, pdata, len);
+       }
+       status = usb_control_msg(udev, pipe, request, reqtype, value, index,
+-                               pIo_buf, len, HZ / 2);
++                               pIo_buf, len, 500);
+       if (status > 0) {  /* Success this control transfer. */
+               if (requesttype == 0x01) {
+                       /* For Control read transfer, we have to copy the read
+diff --git a/drivers/usb/gadget/udc/Kconfig b/drivers/usb/gadget/udc/Kconfig
+index 8c614bb86c665..69394dc1cdfb6 100644
+--- a/drivers/usb/gadget/udc/Kconfig
++++ b/drivers/usb/gadget/udc/Kconfig
+@@ -330,6 +330,7 @@ config USB_AMD5536UDC
+ config USB_FSL_QE
+       tristate "Freescale QE/CPM USB Device Controller"
+       depends on FSL_SOC && (QUICC_ENGINE || CPM)
++      depends on !64BIT || BROKEN
+       help
+          Some of Freescale PowerPC processors have a Full Speed
+          QE/CPM2 USB controller, which support device mode with 4
+diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
+index 1776c05d0a486..1440803216297 100644
+--- a/drivers/usb/host/ehci-hcd.c
++++ b/drivers/usb/host/ehci-hcd.c
+@@ -635,7 +635,16 @@ static int ehci_run (struct usb_hcd *hcd)
+       /* Wait until HC become operational */
+       ehci_readl(ehci, &ehci->regs->command); /* unblock posted writes */
+       msleep(5);
+-      rc = ehci_handshake(ehci, &ehci->regs->status, STS_HALT, 0, 100 * 1000);
++
++      /* For Aspeed, STS_HALT also depends on ASS/PSS status.
++       * Check CMD_RUN instead.
++       */
++      if (ehci->is_aspeed)
++              rc = ehci_handshake(ehci, &ehci->regs->command, CMD_RUN,
++                                  1, 100 * 1000);
++      else
++              rc = ehci_handshake(ehci, &ehci->regs->status, STS_HALT,
++                                  0, 100 * 1000);
+ 
+       up_write(&ehci_cf_port_reset_rwsem);
+ 
+diff --git a/drivers/usb/host/ehci-platform.c 
b/drivers/usb/host/ehci-platform.c
+index c70f2d0b4aaf0..c3dc906274d93 100644
+--- a/drivers/usb/host/ehci-platform.c
++++ b/drivers/usb/host/ehci-platform.c
+@@ -297,6 +297,12 @@ static int ehci_platform_probe(struct platform_device 
*dev)
+                                         "has-transaction-translator"))
+                       hcd->has_tt = 1;
+ 
++              if (of_device_is_compatible(dev->dev.of_node,
++                                          "aspeed,ast2500-ehci") ||
++                  of_device_is_compatible(dev->dev.of_node,
++                                          "aspeed,ast2600-ehci"))
++                      ehci->is_aspeed = 1;
++
+               if (soc_device_match(quirk_poll_match))
+                       priv->quirk_poll = true;
+ 
+diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h
+index 80bb823aa9fe8..fdd073cc053b8 100644
+--- a/drivers/usb/host/ehci.h
++++ b/drivers/usb/host/ehci.h
+@@ -219,6 +219,7 @@ struct ehci_hcd {                  /* one per controller */
+       unsigned                need_oc_pp_cycle:1; /* MPC834X port power */
+       unsigned                imx28_write_fix:1; /* For Freescale i.MX28 */
+       unsigned                spurious_oc:1;
++      unsigned                is_aspeed:1;
+ 
+       /* required for usb32 quirk */
+       #define OHCI_CTRL_HCFS          (3 << 6)
+diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c
+index 98c0f4c1bffd9..51274b87f46c9 100644
+--- a/drivers/usb/musb/musb_gadget.c
++++ b/drivers/usb/musb/musb_gadget.c
+@@ -1247,9 +1247,11 @@ static int musb_gadget_queue(struct usb_ep *ep, struct 
usb_request *req,
+               status = musb_queue_resume_work(musb,
+                                               musb_ep_restart_resume_work,
+                                               request);
+-              if (status < 0)
++              if (status < 0) {
+                       dev_err(musb->controller, "%s resume work: %i\n",
+                               __func__, status);
++                      list_del(&request->list);
++              }
+       }
+ 
+ unlock:
+diff --git a/drivers/usb/storage/unusual_devs.h 
b/drivers/usb/storage/unusual_devs.h
+index c6b3fcf901805..29191d33c0e3e 100644
+--- a/drivers/usb/storage/unusual_devs.h
++++ b/drivers/usb/storage/unusual_devs.h
+@@ -406,6 +406,16 @@ UNUSUAL_DEV(  0x04b8, 0x0602, 0x0110, 0x0110,
+               "785EPX Storage",
+               USB_SC_SCSI, USB_PR_BULK, NULL, US_FL_SINGLE_LUN),
+ 
++/*
++ * Reported by James Buren <[email protected]>
++ * Virtual ISOs cannot be remounted if ejected while the device is locked
++ * Disable locking to mimic Windows behavior that bypasses the issue
++ */
++UNUSUAL_DEV(  0x04c5, 0x2028, 0x0001, 0x0001,
++              "iODD",
++              "2531/2541",
++              USB_SC_DEVICE, USB_PR_DEVICE, NULL, US_FL_NOT_LOCKABLE),
++
+ /*
+  * Not sure who reported this originally but
+  * Pavel Machek <[email protected]> reported that the extra US_FL_SINGLE_LUN
+diff --git a/fs/btrfs/lzo.c b/fs/btrfs/lzo.c
+index 3dbe6eb5fda75..295bbc13ace6a 100644
+--- a/fs/btrfs/lzo.c
++++ b/fs/btrfs/lzo.c
+@@ -357,9 +357,10 @@ int lzo_decompress_bio(struct list_head *ws, struct 
compressed_bio *cb)
+               ASSERT(cur_in / sectorsize ==
+                      (cur_in + LZO_LEN - 1) / sectorsize);
+               cur_page = cb->compressed_pages[cur_in / PAGE_SIZE];
+-              kaddr = kmap(cur_page);
+               ASSERT(cur_page);
++              kaddr = kmap(cur_page);
+               seg_len = read_compress_length(kaddr + offset_in_page(cur_in));
++              kunmap(cur_page);
+               cur_in += LZO_LEN;
+ 
+               /* Copy the compressed segment payload into workspace */
+diff --git a/fs/isofs/inode.c b/fs/isofs/inode.c
+index 678e2c51b855c..0c6eacfcbeef1 100644
+--- a/fs/isofs/inode.c
++++ b/fs/isofs/inode.c
+@@ -1322,6 +1322,8 @@ static int isofs_read_inode(struct inode *inode, int 
relocated)
+ 
+       de = (struct iso_directory_record *) (bh->b_data + offset);
+       de_len = *(unsigned char *) de;
++      if (de_len < sizeof(struct iso_directory_record))
++              goto fail;
+ 
+       if (offset + de_len > bufsize) {
+               int frag1 = bufsize - offset;
+diff --git a/fs/proc/base.c b/fs/proc/base.c
+index 533d5836eb9a4..1f394095eb880 100644
+--- a/fs/proc/base.c
++++ b/fs/proc/base.c
+@@ -67,6 +67,7 @@
+ #include <linux/mm.h>
+ #include <linux/swap.h>
+ #include <linux/rcupdate.h>
++#include <linux/kallsyms.h>
+ #include <linux/stacktrace.h>
+ #include <linux/resource.h>
+ #include <linux/module.h>
+@@ -386,17 +387,19 @@ static int proc_pid_wchan(struct seq_file *m, struct 
pid_namespace *ns,
+                         struct pid *pid, struct task_struct *task)
+ {
+       unsigned long wchan;
++      char symname[KSYM_NAME_LEN];
+ 
+-      if (ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS))
+-              wchan = get_wchan(task);
+-      else
+-              wchan = 0;
++      if (!ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS))
++              goto print0;
+ 
+-      if (wchan)
+-              seq_printf(m, "%ps", (void *) wchan);
+-      else
+-              seq_putc(m, '0');
++      wchan = get_wchan(task);
++      if (wchan && !lookup_symbol_name(wchan, symname)) {
++              seq_puts(m, symname);
++              return 0;
++      }
+ 
++print0:
++      seq_putc(m, '0');
+       return 0;
+ }
+ #endif /* CONFIG_KALLSYMS */
+diff --git a/include/linux/kfence.h b/include/linux/kfence.h
+index 3fe6dd8a18c19..4b5e3679a72c7 100644
+--- a/include/linux/kfence.h
++++ b/include/linux/kfence.h
+@@ -14,6 +14,9 @@
+ 
+ #ifdef CONFIG_KFENCE
+ 
++#include <linux/atomic.h>
++#include <linux/static_key.h>
++
+ /*
+  * We allocate an even number of pages, as it simplifies calculations to map
+  * address to metadata indices; effectively, the very first page serves as an
+@@ -22,13 +25,8 @@
+ #define KFENCE_POOL_SIZE ((CONFIG_KFENCE_NUM_OBJECTS + 1) * 2 * PAGE_SIZE)
+ extern char *__kfence_pool;
+ 
+-#ifdef CONFIG_KFENCE_STATIC_KEYS
+-#include <linux/static_key.h>
+ DECLARE_STATIC_KEY_FALSE(kfence_allocation_key);
+-#else
+-#include <linux/atomic.h>
+ extern atomic_t kfence_allocation_gate;
+-#endif
+ 
+ /**
+  * is_kfence_address() - check if an address belongs to KFENCE pool
+@@ -116,13 +114,16 @@ void *__kfence_alloc(struct kmem_cache *s, size_t size, 
gfp_t flags);
+  */
+ static __always_inline void *kfence_alloc(struct kmem_cache *s, size_t size, 
gfp_t flags)
+ {
+-#ifdef CONFIG_KFENCE_STATIC_KEYS
+-      if (static_branch_unlikely(&kfence_allocation_key))
++#if defined(CONFIG_KFENCE_STATIC_KEYS) || CONFIG_KFENCE_SAMPLE_INTERVAL == 0
++      if (!static_branch_unlikely(&kfence_allocation_key))
++              return NULL;
+ #else
+-      if (unlikely(!atomic_read(&kfence_allocation_gate)))
++      if (!static_branch_likely(&kfence_allocation_key))
++              return NULL;
+ #endif
+-              return __kfence_alloc(s, size, flags);
+-      return NULL;
++      if (likely(atomic_read(&kfence_allocation_gate)))
++              return NULL;
++      return __kfence_alloc(s, size, flags);
+ }
+ 
+ /**
+diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h
+index 2adeea44c0d53..61590c1f2d333 100644
+--- a/include/linux/lsm_hook_defs.h
++++ b/include/linux/lsm_hook_defs.h
+@@ -26,13 +26,13 @@
+  *   #undef LSM_HOOK
+  * };
+  */
+-LSM_HOOK(int, 0, binder_set_context_mgr, struct task_struct *mgr)
+-LSM_HOOK(int, 0, binder_transaction, struct task_struct *from,
+-       struct task_struct *to)
+-LSM_HOOK(int, 0, binder_transfer_binder, struct task_struct *from,
+-       struct task_struct *to)
+-LSM_HOOK(int, 0, binder_transfer_file, struct task_struct *from,
+-       struct task_struct *to, struct file *file)
++LSM_HOOK(int, 0, binder_set_context_mgr, const struct cred *mgr)
++LSM_HOOK(int, 0, binder_transaction, const struct cred *from,
++       const struct cred *to)
++LSM_HOOK(int, 0, binder_transfer_binder, const struct cred *from,
++       const struct cred *to)
++LSM_HOOK(int, 0, binder_transfer_file, const struct cred *from,
++       const struct cred *to, struct file *file)
+ LSM_HOOK(int, 0, ptrace_access_check, struct task_struct *child,
+        unsigned int mode)
+ LSM_HOOK(int, 0, ptrace_traceme, struct task_struct *parent)
+diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
+index 5c4c5c0602cb7..59024618554e2 100644
+--- a/include/linux/lsm_hooks.h
++++ b/include/linux/lsm_hooks.h
+@@ -1313,22 +1313,22 @@
+  *
+  * @binder_set_context_mgr:
+  *    Check whether @mgr is allowed to be the binder context manager.
+- *    @mgr contains the task_struct for the task being registered.
++ *    @mgr contains the struct cred for the current binder process.
+  *    Return 0 if permission is granted.
+  * @binder_transaction:
+  *    Check whether @from is allowed to invoke a binder transaction call
+  *    to @to.
+- *    @from contains the task_struct for the sending task.
+- *    @to contains the task_struct for the receiving task.
++ *    @from contains the struct cred for the sending process.
++ *    @to contains the struct cred for the receiving process.
+  * @binder_transfer_binder:
+  *    Check whether @from is allowed to transfer a binder reference to @to.
+- *    @from contains the task_struct for the sending task.
+- *    @to contains the task_struct for the receiving task.
++ *    @from contains the struct cred for the sending process.
++ *    @to contains the struct cred for the receiving process.
+  * @binder_transfer_file:
+  *    Check whether @from is allowed to transfer @file to @to.
+- *    @from contains the task_struct for the sending task.
++ *    @from contains the struct cred for the sending process.
+  *    @file contains the struct file being transferred.
+- *    @to contains the task_struct for the receiving task.
++ *    @to contains the struct cred for the receiving process.
+  *
+  * @ptrace_access_check:
+  *    Check permission before allowing the current process to trace the
+diff --git a/include/linux/security.h b/include/linux/security.h
+index 5b7288521300b..46a02ce34d00b 100644
+--- a/include/linux/security.h
++++ b/include/linux/security.h
+@@ -258,13 +258,13 @@ extern int security_init(void);
+ extern int early_security_init(void);
+ 
+ /* Security operations */
+-int security_binder_set_context_mgr(struct task_struct *mgr);
+-int security_binder_transaction(struct task_struct *from,
+-                              struct task_struct *to);
+-int security_binder_transfer_binder(struct task_struct *from,
+-                                  struct task_struct *to);
+-int security_binder_transfer_file(struct task_struct *from,
+-                                struct task_struct *to, struct file *file);
++int security_binder_set_context_mgr(const struct cred *mgr);
++int security_binder_transaction(const struct cred *from,
++                              const struct cred *to);
++int security_binder_transfer_binder(const struct cred *from,
++                                  const struct cred *to);
++int security_binder_transfer_file(const struct cred *from,
++                                const struct cred *to, struct file *file);
+ int security_ptrace_access_check(struct task_struct *child, unsigned int 
mode);
+ int security_ptrace_traceme(struct task_struct *parent);
+ int security_capget(struct task_struct *target,
+@@ -508,25 +508,25 @@ static inline int early_security_init(void)
+       return 0;
+ }
+ 
+-static inline int security_binder_set_context_mgr(struct task_struct *mgr)
++static inline int security_binder_set_context_mgr(const struct cred *mgr)
+ {
+       return 0;
+ }
+ 
+-static inline int security_binder_transaction(struct task_struct *from,
+-                                            struct task_struct *to)
++static inline int security_binder_transaction(const struct cred *from,
++                                            const struct cred *to)
+ {
+       return 0;
+ }
+ 
+-static inline int security_binder_transfer_binder(struct task_struct *from,
+-                                                struct task_struct *to)
++static inline int security_binder_transfer_binder(const struct cred *from,
++                                                const struct cred *to)
+ {
+       return 0;
+ }
+ 
+-static inline int security_binder_transfer_file(struct task_struct *from,
+-                                              struct task_struct *to,
++static inline int security_binder_transfer_file(const struct cred *from,
++                                              const struct cred *to,
+                                               struct file *file)
+ {
+       return 0;
+@@ -1041,6 +1041,11 @@ static inline void security_transfer_creds(struct cred 
*new,
+ {
+ }
+ 
++static inline void security_cred_getsecid(const struct cred *c, u32 *secid)
++{
++      *secid = 0;
++}
++
+ static inline int security_kernel_act_as(struct cred *cred, u32 secid)
+ {
+       return 0;
+diff --git a/lib/Kconfig.kfence b/lib/Kconfig.kfence
+index e641add339475..912f252a41fc6 100644
+--- a/lib/Kconfig.kfence
++++ b/lib/Kconfig.kfence
+@@ -25,17 +25,6 @@ menuconfig KFENCE
+ 
+ if KFENCE
+ 
+-config KFENCE_STATIC_KEYS
+-      bool "Use static keys to set up allocations"
+-      default y
+-      depends on JUMP_LABEL # To ensure performance, require jump labels
+-      help
+-        Use static keys (static branches) to set up KFENCE allocations. Using
+-        static keys is normally recommended, because it avoids a dynamic
+-        branch in the allocator's fast path. However, with very low sample
+-        intervals, or on systems that do not support jump labels, a dynamic
+-        branch may still be an acceptable performance trade-off.
+-
+ config KFENCE_SAMPLE_INTERVAL
+       int "Default sample interval in milliseconds"
+       default 100
+@@ -56,6 +45,21 @@ config KFENCE_NUM_OBJECTS
+         pages are required; with one containing the object and two adjacent
+         ones used as guard pages.
+ 
++config KFENCE_STATIC_KEYS
++      bool "Use static keys to set up allocations" if EXPERT
++      depends on JUMP_LABEL
++      help
++        Use static keys (static branches) to set up KFENCE allocations. This
++        option is only recommended when using very large sample intervals, or
++        performance has carefully been evaluated with this option.
++
++        Using static keys comes with trade-offs that need to be carefully
++        evaluated given target workloads and system architectures. Notably,
++        enabling and disabling static keys invoke IPI broadcasts, the latency
++        and impact of which is much harder to predict than a dynamic branch.
++
++        Say N if you are unsure.
++
+ config KFENCE_STRESS_TEST_FAULTS
+       int "Stress testing of fault handling and error reporting" if EXPERT
+       default 0
+diff --git a/mm/kfence/core.c b/mm/kfence/core.c
+index 7a97db8bc8e75..4b69236aea722 100644
+--- a/mm/kfence/core.c
++++ b/mm/kfence/core.c
+@@ -97,10 +97,11 @@ struct kfence_metadata 
kfence_metadata[CONFIG_KFENCE_NUM_OBJECTS];
+ static struct list_head kfence_freelist = LIST_HEAD_INIT(kfence_freelist);
+ static DEFINE_RAW_SPINLOCK(kfence_freelist_lock); /* Lock protecting 
freelist. */
+ 
+-#ifdef CONFIG_KFENCE_STATIC_KEYS
+-/* The static key to set up a KFENCE allocation. */
++/*
++ * The static key to set up a KFENCE allocation; or if static keys are not 
used
++ * to gate allocations, to avoid a load and compare if KFENCE is disabled.
++ */
+ DEFINE_STATIC_KEY_FALSE(kfence_allocation_key);
+-#endif
+ 
+ /* Gates the allocation, ensuring only one succeeds in a given period. */
+ atomic_t kfence_allocation_gate = ATOMIC_INIT(1);
+@@ -668,6 +669,8 @@ void __init kfence_init(void)
+               return;
+       }
+ 
++      if (!IS_ENABLED(CONFIG_KFENCE_STATIC_KEYS))
++              static_branch_enable(&kfence_allocation_key);
+       WRITE_ONCE(kfence_enabled, true);
+       queue_delayed_work(system_unbound_wq, &kfence_timer, 0);
+       pr_info("initialized - using %lu bytes for %d objects at 0x%p-0x%p\n", 
KFENCE_POOL_SIZE,
+@@ -752,12 +755,7 @@ void *__kfence_alloc(struct kmem_cache *s, size_t size, 
gfp_t flags)
+           (s->flags & (SLAB_CACHE_DMA | SLAB_CACHE_DMA32)))
+               return NULL;
+ 
+-      /*
+-       * allocation_gate only needs to become non-zero, so it doesn't make
+-       * sense to continue writing to it and pay the associated contention
+-       * cost, in case we have a large number of concurrent allocations.
+-       */
+-      if (atomic_read(&kfence_allocation_gate) || 
atomic_inc_return(&kfence_allocation_gate) > 1)
++      if (atomic_inc_return(&kfence_allocation_gate) > 1)
+               return NULL;
+ #ifdef CONFIG_KFENCE_STATIC_KEYS
+       /*
+diff --git a/security/security.c b/security/security.c
+index 9ffa9e9c5c554..67264cb08fb31 100644
+--- a/security/security.c
++++ b/security/security.c
+@@ -747,25 +747,25 @@ static int lsm_superblock_alloc(struct super_block *sb)
+ 
+ /* Security operations */
+ 
+-int security_binder_set_context_mgr(struct task_struct *mgr)
++int security_binder_set_context_mgr(const struct cred *mgr)
+ {
+       return call_int_hook(binder_set_context_mgr, 0, mgr);
+ }
+ 
+-int security_binder_transaction(struct task_struct *from,
+-                              struct task_struct *to)
++int security_binder_transaction(const struct cred *from,
++                              const struct cred *to)
+ {
+       return call_int_hook(binder_transaction, 0, from, to);
+ }
+ 
+-int security_binder_transfer_binder(struct task_struct *from,
+-                                  struct task_struct *to)
++int security_binder_transfer_binder(const struct cred *from,
++                                  const struct cred *to)
+ {
+       return call_int_hook(binder_transfer_binder, 0, from, to);
+ }
+ 
+-int security_binder_transfer_file(struct task_struct *from,
+-                                struct task_struct *to, struct file *file)
++int security_binder_transfer_file(const struct cred *from,
++                                const struct cred *to, struct file *file)
+ {
+       return call_int_hook(binder_transfer_file, 0, from, to, file);
+ }
+diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
+index e7ebd45ca3457..c8bf3db90c8ba 100644
+--- a/security/selinux/hooks.c
++++ b/security/selinux/hooks.c
+@@ -255,29 +255,6 @@ static inline u32 task_sid_obj(const struct task_struct 
*task)
+       return sid;
+ }
+ 
+-/*
+- * get the security ID of a task for use with binder
+- */
+-static inline u32 task_sid_binder(const struct task_struct *task)
+-{
+-      /*
+-       * In many case where this function is used we should be using the
+-       * task's subjective SID, but we can't reliably access the subjective
+-       * creds of a task other than our own so we must use the objective
+-       * creds/SID, which are safe to access.  The downside is that if a task
+-       * is temporarily overriding it's creds it will not be reflected here;
+-       * however, it isn't clear that binder would handle that case well
+-       * anyway.
+-       *
+-       * If this ever changes and we can safely reference the subjective
+-       * creds/SID of another task, this function will make it easier to
+-       * identify the various places where we make use of the task SIDs in
+-       * the binder code.  It is also likely that we will need to adjust
+-       * the main drivers/android binder code as well.
+-       */
+-      return task_sid_obj(task);
+-}
+-
+ static int inode_doinit_with_dentry(struct inode *inode, struct dentry 
*opt_dentry);
+ 
+ /*
+@@ -2066,18 +2043,19 @@ static inline u32 open_file_to_av(struct file *file)
+ 
+ /* Hook functions begin here. */
+ 
+-static int selinux_binder_set_context_mgr(struct task_struct *mgr)
++static int selinux_binder_set_context_mgr(const struct cred *mgr)
+ {
+       return avc_has_perm(&selinux_state,
+-                          current_sid(), task_sid_binder(mgr), 
SECCLASS_BINDER,
++                          current_sid(), cred_sid(mgr), SECCLASS_BINDER,
+                           BINDER__SET_CONTEXT_MGR, NULL);
+ }
+ 
+-static int selinux_binder_transaction(struct task_struct *from,
+-                                    struct task_struct *to)
++static int selinux_binder_transaction(const struct cred *from,
++                                    const struct cred *to)
+ {
+       u32 mysid = current_sid();
+-      u32 fromsid = task_sid_binder(from);
++      u32 fromsid = cred_sid(from);
++      u32 tosid = cred_sid(to);
+       int rc;
+ 
+       if (mysid != fromsid) {
+@@ -2088,24 +2066,24 @@ static int selinux_binder_transaction(struct 
task_struct *from,
+                       return rc;
+       }
+ 
+-      return avc_has_perm(&selinux_state, fromsid, task_sid_binder(to),
++      return avc_has_perm(&selinux_state, fromsid, tosid,
+                           SECCLASS_BINDER, BINDER__CALL, NULL);
+ }
+ 
+-static int selinux_binder_transfer_binder(struct task_struct *from,
+-                                        struct task_struct *to)
++static int selinux_binder_transfer_binder(const struct cred *from,
++                                        const struct cred *to)
+ {
+       return avc_has_perm(&selinux_state,
+-                          task_sid_binder(from), task_sid_binder(to),
++                          cred_sid(from), cred_sid(to),
+                           SECCLASS_BINDER, BINDER__TRANSFER,
+                           NULL);
+ }
+ 
+-static int selinux_binder_transfer_file(struct task_struct *from,
+-                                      struct task_struct *to,
++static int selinux_binder_transfer_file(const struct cred *from,
++                                      const struct cred *to,
+                                       struct file *file)
+ {
+-      u32 sid = task_sid_binder(to);
++      u32 sid = cred_sid(to);
+       struct file_security_struct *fsec = selinux_file(file);
+       struct dentry *dentry = file->f_path.dentry;
+       struct inode_security_struct *isec;

Reply via email to