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;
