diff --git a/COPYING-6.12.0-124.31.1.el10 b/COPYING-6.12.0-124.35.1.el10 similarity index 100% rename from COPYING-6.12.0-124.31.1.el10 rename to COPYING-6.12.0-124.35.1.el10 diff --git a/Documentation/networking/bonding.rst b/Documentation/networking/bonding.rst index 7c8d22d686..7d86e6a086 100644 --- a/Documentation/networking/bonding.rst +++ b/Documentation/networking/bonding.rst @@ -562,6 +562,12 @@ lacp_rate The default is slow. +broadcast_neighbor + + Option specifying whether to broadcast ARP/ND packets to all + active slaves. This option has no effect in modes other than + 802.3ad mode. The default is off (0). + max_bonds Specifies the number of bonding devices to create for this diff --git a/Makefile.rhelver b/Makefile.rhelver index e4427791af..f4fc763e3b 100644 --- a/Makefile.rhelver +++ b/Makefile.rhelver @@ -12,7 +12,7 @@ RHEL_MINOR = 1 # # Use this spot to avoid future merge conflicts. # Do not trim this comment. -RHEL_RELEASE = 124.31.1 +RHEL_RELEASE = 124.35.1 # # RHEL_REBASE_NUM diff --git a/configs/kernel-6.12.0-ppc64le-debug.config b/configs/kernel-6.12.0-ppc64le-debug.config index 1b844fbe97..f941e92267 100644 --- a/configs/kernel-6.12.0-ppc64le-debug.config +++ b/configs/kernel-6.12.0-ppc64le-debug.config @@ -500,9 +500,6 @@ CONFIG_PPC_TRANSACTIONAL_MEM=y CONFIG_PPC_UV=y # CONFIG_LD_HEAD_STUB_CATCH is not set CONFIG_MPROFILE_KERNEL=y -CONFIG_ARCH_USING_PATCHABLE_FUNCTION_ENTRY=y -CONFIG_PPC_FTRACE_OUT_OF_LINE=y -CONFIG_PPC_FTRACE_OUT_OF_LINE_NUM_RESERVE=32768 CONFIG_HOTPLUG_CPU=y CONFIG_INTERRUPT_SANITIZE_REGISTERS=y CONFIG_PPC_QUEUED_SPINLOCKS=y @@ -725,7 +722,6 @@ CONFIG_FUNCTION_ALIGNMENT_4B=y CONFIG_FUNCTION_ALIGNMENT=4 CONFIG_CC_HAS_MIN_FUNCTION_ALIGNMENT=y CONFIG_CC_HAS_SANE_FUNCTION_ALIGNMENT=y -CONFIG_ARCH_WANTS_PRE_LINK_VMLINUX=y # end of General architecture-dependent options CONFIG_RT_MUTEXES=y @@ -5030,7 +5026,6 @@ CONFIG_HID_KUNIT_TEST=m # # HID-BPF support # -CONFIG_HID_BPF=y # end of HID-BPF support CONFIG_I2C_HID=y @@ -7132,8 +7127,6 @@ CONFIG_HAVE_FUNCTION_TRACER=y CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y CONFIG_HAVE_DYNAMIC_FTRACE=y CONFIG_HAVE_DYNAMIC_FTRACE_WITH_REGS=y -CONFIG_HAVE_DYNAMIC_FTRACE_WITH_DIRECT_CALLS=y -CONFIG_HAVE_DYNAMIC_FTRACE_WITH_CALL_OPS=y CONFIG_HAVE_DYNAMIC_FTRACE_WITH_ARGS=y CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y CONFIG_HAVE_SYSCALL_TRACEPOINTS=y @@ -7154,8 +7147,6 @@ CONFIG_FUNCTION_TRACER=y CONFIG_FUNCTION_GRAPH_TRACER=y CONFIG_DYNAMIC_FTRACE=y CONFIG_DYNAMIC_FTRACE_WITH_REGS=y -CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS=y -CONFIG_DYNAMIC_FTRACE_WITH_CALL_OPS=y CONFIG_DYNAMIC_FTRACE_WITH_ARGS=y CONFIG_FPROBE=y CONFIG_FUNCTION_PROFILER=y @@ -7180,7 +7171,7 @@ CONFIG_BPF_EVENTS=y CONFIG_DYNAMIC_EVENTS=y CONFIG_PROBE_EVENTS=y CONFIG_FTRACE_MCOUNT_RECORD=y -CONFIG_FTRACE_MCOUNT_USE_PATCHABLE_FUNCTION_ENTRY=y +CONFIG_FTRACE_MCOUNT_USE_CC=y CONFIG_TRACING_MAP=y CONFIG_SYNTH_EVENTS=y # CONFIG_USER_EVENTS is not set @@ -7206,8 +7197,6 @@ CONFIG_RV_REACTORS=y CONFIG_RV_REACT_PRINTK=y CONFIG_RV_REACT_PANIC=y # CONFIG_SAMPLES is not set -CONFIG_HAVE_SAMPLE_FTRACE_DIRECT=y -CONFIG_HAVE_SAMPLE_FTRACE_DIRECT_MULTI=y CONFIG_ARCH_HAS_DEVMEM_IS_ALLOWED=y CONFIG_STRICT_DEVMEM=y # CONFIG_IO_STRICT_DEVMEM is not set diff --git a/configs/kernel-6.12.0-ppc64le.config b/configs/kernel-6.12.0-ppc64le.config index 7f13ef0d12..8379c8236b 100644 --- a/configs/kernel-6.12.0-ppc64le.config +++ b/configs/kernel-6.12.0-ppc64le.config @@ -498,6 +498,9 @@ CONFIG_PPC_TRANSACTIONAL_MEM=y CONFIG_PPC_UV=y # CONFIG_LD_HEAD_STUB_CATCH is not set CONFIG_MPROFILE_KERNEL=y +CONFIG_ARCH_USING_PATCHABLE_FUNCTION_ENTRY=y +CONFIG_PPC_FTRACE_OUT_OF_LINE=y +CONFIG_PPC_FTRACE_OUT_OF_LINE_NUM_RESERVE=32768 CONFIG_HOTPLUG_CPU=y CONFIG_INTERRUPT_SANITIZE_REGISTERS=y CONFIG_PPC_QUEUED_SPINLOCKS=y @@ -721,6 +724,7 @@ CONFIG_FUNCTION_ALIGNMENT_4B=y CONFIG_FUNCTION_ALIGNMENT=4 CONFIG_CC_HAS_MIN_FUNCTION_ALIGNMENT=y CONFIG_CC_HAS_SANE_FUNCTION_ALIGNMENT=y +CONFIG_ARCH_WANTS_PRE_LINK_VMLINUX=y # end of General architecture-dependent options CONFIG_RT_MUTEXES=y @@ -5024,6 +5028,7 @@ CONFIG_HID_KUNIT_TEST=m # # HID-BPF support # +CONFIG_HID_BPF=y # end of HID-BPF support CONFIG_I2C_HID=y @@ -7093,6 +7098,8 @@ CONFIG_HAVE_FUNCTION_TRACER=y CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y CONFIG_HAVE_DYNAMIC_FTRACE=y CONFIG_HAVE_DYNAMIC_FTRACE_WITH_REGS=y +CONFIG_HAVE_DYNAMIC_FTRACE_WITH_DIRECT_CALLS=y +CONFIG_HAVE_DYNAMIC_FTRACE_WITH_CALL_OPS=y CONFIG_HAVE_DYNAMIC_FTRACE_WITH_ARGS=y CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y CONFIG_HAVE_SYSCALL_TRACEPOINTS=y @@ -7112,6 +7119,8 @@ CONFIG_FUNCTION_TRACER=y CONFIG_FUNCTION_GRAPH_TRACER=y CONFIG_DYNAMIC_FTRACE=y CONFIG_DYNAMIC_FTRACE_WITH_REGS=y +CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS=y +CONFIG_DYNAMIC_FTRACE_WITH_CALL_OPS=y CONFIG_DYNAMIC_FTRACE_WITH_ARGS=y CONFIG_FPROBE=y CONFIG_FUNCTION_PROFILER=y @@ -7136,7 +7145,7 @@ CONFIG_BPF_EVENTS=y CONFIG_DYNAMIC_EVENTS=y CONFIG_PROBE_EVENTS=y CONFIG_FTRACE_MCOUNT_RECORD=y -CONFIG_FTRACE_MCOUNT_USE_CC=y +CONFIG_FTRACE_MCOUNT_USE_PATCHABLE_FUNCTION_ENTRY=y CONFIG_TRACING_MAP=y CONFIG_SYNTH_EVENTS=y # CONFIG_USER_EVENTS is not set @@ -7162,6 +7171,8 @@ CONFIG_RV_REACTORS=y CONFIG_RV_REACT_PRINTK=y CONFIG_RV_REACT_PANIC=y # CONFIG_SAMPLES is not set +CONFIG_HAVE_SAMPLE_FTRACE_DIRECT=y +CONFIG_HAVE_SAMPLE_FTRACE_DIRECT_MULTI=y CONFIG_ARCH_HAS_DEVMEM_IS_ALLOWED=y CONFIG_STRICT_DEVMEM=y # CONFIG_IO_STRICT_DEVMEM is not set diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 8aacbe40ec..483671421a 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -211,6 +211,8 @@ atomic_t netpoll_block_tx = ATOMIC_INIT(0); unsigned int bond_net_id __read_mostly; +DEFINE_STATIC_KEY_FALSE(bond_bcast_neigh_enabled); + static const struct flow_dissector_key flow_keys_bonding_keys[] = { { .key_id = FLOW_DISSECTOR_KEY_CONTROL, @@ -2364,7 +2366,9 @@ skip_mac_set: unblock_netpoll_tx(); } - if (bond_mode_can_use_xmit_hash(bond)) + /* broadcast mode uses the all_slaves to loop through slaves. */ + if (bond_mode_can_use_xmit_hash(bond) || + BOND_MODE(bond) == BOND_MODE_BROADCAST) bond_update_slave_arr(bond, NULL); if (!slave_dev->netdev_ops->ndo_bpf || @@ -2540,7 +2544,8 @@ static int __bond_release_one(struct net_device *bond_dev, bond_upper_dev_unlink(bond, slave); - if (bond_mode_can_use_xmit_hash(bond)) + if (bond_mode_can_use_xmit_hash(bond) || + BOND_MODE(bond) == BOND_MODE_BROADCAST) bond_update_slave_arr(bond, slave); slave_info(bond_dev, slave_dev, "Releasing %s interface\n", @@ -4450,6 +4455,9 @@ static int bond_open(struct net_device *bond_dev) bond_for_each_slave(bond, slave, iter) dev_mc_add(slave->dev, lacpdu_mcast_addr); + + if (bond->params.broadcast_neighbor) + static_branch_inc(&bond_bcast_neigh_enabled); } if (bond_mode_can_use_xmit_hash(bond)) @@ -4469,6 +4477,10 @@ static int bond_close(struct net_device *bond_dev) bond_alb_deinitialize(bond); bond->recv_probe = NULL; + if (BOND_MODE(bond) == BOND_MODE_8023AD && + bond->params.broadcast_neighbor) + static_branch_dec(&bond_bcast_neigh_enabled); + if (bond_uses_primary(bond)) { rcu_read_lock(); slave = rcu_dereference(bond->curr_active_slave); @@ -5305,6 +5317,37 @@ static struct slave *bond_xdp_xmit_3ad_xor_slave_get(struct bonding *bond, return slaves->arr[hash % count]; } +static bool bond_should_broadcast_neighbor(struct sk_buff *skb, + struct net_device *dev) +{ + struct bonding *bond = netdev_priv(dev); + struct { + struct ipv6hdr ip6; + struct icmp6hdr icmp6; + } *combined, _combined; + + if (!static_branch_unlikely(&bond_bcast_neigh_enabled)) + return false; + + if (!bond->params.broadcast_neighbor) + return false; + + if (skb->protocol == htons(ETH_P_ARP)) + return true; + + if (skb->protocol == htons(ETH_P_IPV6)) { + combined = skb_header_pointer(skb, skb_mac_header_len(skb), + sizeof(_combined), + &_combined); + if (combined && combined->ip6.nexthdr == NEXTHDR_ICMP && + (combined->icmp6.icmp6_type == NDISC_NEIGHBOUR_SOLICITATION || + combined->icmp6.icmp6_type == NDISC_NEIGHBOUR_ADVERTISEMENT)) + return true; + } + + return false; +} + /* Use this Xmit function for 3AD as well as XOR modes. The current * usable slave array is formed in the control path. The xmit function * just calculates hash and sends the packet out. @@ -5324,17 +5367,27 @@ static netdev_tx_t bond_3ad_xor_xmit(struct sk_buff *skb, return bond_tx_drop(dev, skb); } -/* in broadcast mode, we send everything to all usable interfaces. */ +/* in broadcast mode, we send everything to all or usable slave interfaces. + * under rcu_read_lock when this function is called. + */ static netdev_tx_t bond_xmit_broadcast(struct sk_buff *skb, - struct net_device *bond_dev) + struct net_device *bond_dev, + bool all_slaves) { struct bonding *bond = netdev_priv(bond_dev); - struct slave *slave = NULL; - struct list_head *iter; + struct bond_up_slave *slaves; bool xmit_suc = false; bool skb_used = false; + int slaves_count, i; - bond_for_each_slave_rcu(bond, slave, iter) { + if (all_slaves) + slaves = rcu_dereference(bond->all_slaves); + else + slaves = rcu_dereference(bond->usable_slaves); + + slaves_count = slaves ? READ_ONCE(slaves->count) : 0; + for (i = 0; i < slaves_count; i++) { + struct slave *slave = slaves->arr[i]; struct sk_buff *skb2; if (!(bond_slave_is_up(slave) && slave->link == BOND_LINK_UP)) @@ -5572,10 +5625,13 @@ static netdev_tx_t __bond_start_xmit(struct sk_buff *skb, struct net_device *dev case BOND_MODE_ACTIVEBACKUP: return bond_xmit_activebackup(skb, dev); case BOND_MODE_8023AD: + if (bond_should_broadcast_neighbor(skb, dev)) + return bond_xmit_broadcast(skb, dev, false); + fallthrough; case BOND_MODE_XOR: return bond_3ad_xor_xmit(skb, dev); case BOND_MODE_BROADCAST: - return bond_xmit_broadcast(skb, dev); + return bond_xmit_broadcast(skb, dev, true); case BOND_MODE_ALB: return bond_alb_xmit(skb, dev); case BOND_MODE_TLB: @@ -6451,6 +6507,7 @@ static int __init bond_check_params(struct bond_params *params) eth_zero_addr(params->ad_actor_system); params->ad_user_port_key = ad_user_port_key; params->coupled_control = 1; + params->broadcast_neighbor = 0; if (packets_per_slave > 0) { params->reciprocal_packets_per_slave = reciprocal_value(packets_per_slave); diff --git a/drivers/net/bonding/bond_netlink.c b/drivers/net/bonding/bond_netlink.c index 2a6a424806..b057d89942 100644 --- a/drivers/net/bonding/bond_netlink.c +++ b/drivers/net/bonding/bond_netlink.c @@ -124,6 +124,7 @@ static const struct nla_policy bond_policy[IFLA_BOND_MAX + 1] = { [IFLA_BOND_MISSED_MAX] = { .type = NLA_U8 }, [IFLA_BOND_NS_IP6_TARGET] = { .type = NLA_NESTED }, [IFLA_BOND_COUPLED_CONTROL] = { .type = NLA_U8 }, + [IFLA_BOND_BROADCAST_NEIGH] = { .type = NLA_U8 }, }; static const struct nla_policy bond_slave_policy[IFLA_BOND_SLAVE_MAX + 1] = { @@ -561,6 +562,16 @@ static int bond_changelink(struct net_device *bond_dev, struct nlattr *tb[], return err; } + if (data[IFLA_BOND_BROADCAST_NEIGH]) { + int broadcast_neigh = nla_get_u8(data[IFLA_BOND_BROADCAST_NEIGH]); + + bond_opt_initval(&newval, broadcast_neigh); + err = __bond_opt_set(bond, BOND_OPT_BROADCAST_NEIGH, &newval, + data[IFLA_BOND_BROADCAST_NEIGH], extack); + if (err) + return err; + } + return 0; } @@ -628,6 +639,7 @@ static size_t bond_get_size(const struct net_device *bond_dev) nla_total_size(sizeof(struct nlattr)) + nla_total_size(sizeof(struct in6_addr)) * BOND_MAX_NS_TARGETS + nla_total_size(sizeof(u8)) + /* IFLA_BOND_COUPLED_CONTROL */ + nla_total_size(sizeof(u8)) + /* IFLA_BOND_BROADCAST_NEIGH */ 0; } @@ -791,6 +803,10 @@ static int bond_fill_info(struct sk_buff *skb, bond->params.coupled_control)) goto nla_put_failure; + if (nla_put_u8(skb, IFLA_BOND_BROADCAST_NEIGH, + bond->params.broadcast_neighbor)) + goto nla_put_failure; + if (BOND_MODE(bond) == BOND_MODE_8023AD) { struct ad_info info; diff --git a/drivers/net/bonding/bond_options.c b/drivers/net/bonding/bond_options.c index 91893c29b8..1d639a3be6 100644 --- a/drivers/net/bonding/bond_options.c +++ b/drivers/net/bonding/bond_options.c @@ -87,6 +87,8 @@ static int bond_option_missed_max_set(struct bonding *bond, const struct bond_opt_value *newval); static int bond_option_coupled_control_set(struct bonding *bond, const struct bond_opt_value *newval); +static int bond_option_broadcast_neigh_set(struct bonding *bond, + const struct bond_opt_value *newval); static const struct bond_opt_value bond_mode_tbl[] = { { "balance-rr", BOND_MODE_ROUNDROBIN, BOND_VALFLAG_DEFAULT}, @@ -240,6 +242,12 @@ static const struct bond_opt_value bond_coupled_control_tbl[] = { { NULL, -1, 0}, }; +static const struct bond_opt_value bond_broadcast_neigh_tbl[] = { + { "off", 0, BOND_VALFLAG_DEFAULT}, + { "on", 1, 0}, + { NULL, -1, 0} +}; + static const struct bond_option bond_opts[BOND_OPT_LAST] = { [BOND_OPT_MODE] = { .id = BOND_OPT_MODE, @@ -513,6 +521,14 @@ static const struct bond_option bond_opts[BOND_OPT_LAST] = { .flags = BOND_OPTFLAG_IFDOWN, .values = bond_coupled_control_tbl, .set = bond_option_coupled_control_set, + }, + [BOND_OPT_BROADCAST_NEIGH] = { + .id = BOND_OPT_BROADCAST_NEIGH, + .name = "broadcast_neighbor", + .desc = "Broadcast neighbor packets to all active slaves", + .unsuppmodes = BOND_MODE_ALL_EX(BIT(BOND_MODE_8023AD)), + .values = bond_broadcast_neigh_tbl, + .set = bond_option_broadcast_neigh_set, } }; @@ -894,6 +910,13 @@ static int bond_option_mode_set(struct bonding *bond, bond->params.arp_validate = BOND_ARP_VALIDATE_NONE; bond->params.mode = newval->value; + /* When changing mode, the bond device is down, we may reduce + * the bond_bcast_neigh_enabled in bond_close() if broadcast_neighbor + * enabled in 8023ad mode. Therefore, only clear broadcast_neighbor + * to 0. + */ + bond->params.broadcast_neighbor = 0; + if (bond->dev->reg_state == NETREG_REGISTERED) { bool update = false; @@ -1840,3 +1863,22 @@ static int bond_option_coupled_control_set(struct bonding *bond, bond->params.coupled_control = newval->value; return 0; } + +static int bond_option_broadcast_neigh_set(struct bonding *bond, + const struct bond_opt_value *newval) +{ + if (bond->params.broadcast_neighbor == newval->value) + return 0; + + bond->params.broadcast_neighbor = newval->value; + if (bond->dev->flags & IFF_UP) { + if (bond->params.broadcast_neighbor) + static_branch_inc(&bond_bcast_neigh_enabled); + else + static_branch_dec(&bond_bcast_neigh_enabled); + } + + netdev_dbg(bond->dev, "Setting broadcast_neighbor to %s (%llu)\n", + newval->string, newval->value); + return 0; +} diff --git a/drivers/net/ethernet/intel/ice/ice_lag.c b/drivers/net/ethernet/intel/ice/ice_lag.c index 2410aee59f..1b3b1776e8 100644 --- a/drivers/net/ethernet/intel/ice/ice_lag.c +++ b/drivers/net/ethernet/intel/ice/ice_lag.c @@ -704,7 +704,7 @@ void ice_lag_move_new_vf_nodes(struct ice_vf *vf) lag = pf->lag; mutex_lock(&pf->lag_mutex); - if (!lag->bonded) + if (!lag || !lag->bonded) goto new_vf_unlock; pri_port = pf->hw.port_info->lport; diff --git a/drivers/net/ethernet/intel/ice/ice_txrx.c b/drivers/net/ethernet/intel/ice/ice_txrx.c index 72de666acc..1cfb9b52ac 100644 --- a/drivers/net/ethernet/intel/ice/ice_txrx.c +++ b/drivers/net/ethernet/intel/ice/ice_txrx.c @@ -919,8 +919,10 @@ ice_get_rx_buf(struct ice_rx_ring *rx_ring, const unsigned int size, rx_buf = &rx_ring->rx_buf[ntc]; prefetchw(rx_buf->page); - if (!size) + if (!size) { + rx_buf->pagecnt_bias--; return rx_buf; + } /* we are reusing so sync this buffer for CPU use */ dma_sync_single_range_for_cpu(rx_ring->dev, rx_buf->dma, rx_buf->page_offset, size, diff --git a/drivers/video/fbdev/core/bitblit.c b/drivers/video/fbdev/core/bitblit.c index 3ff1b2a865..525c1b4c60 100644 --- a/drivers/video/fbdev/core/bitblit.c +++ b/drivers/video/fbdev/core/bitblit.c @@ -80,12 +80,16 @@ static inline void bit_putcs_aligned(struct vc_data *vc, struct fb_info *info, struct fb_image *image, u8 *buf, u8 *dst) { u16 charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff; + unsigned int charcnt = vc->vc_font.charcount; u32 idx = vc->vc_font.width >> 3; u8 *src; while (cnt--) { - src = vc->vc_font.data + (scr_readw(s++)& - charmask)*cellsize; + u16 ch = scr_readw(s++) & charmask; + + if (ch >= charcnt) + ch = 0; + src = vc->vc_font.data + (unsigned int)ch * cellsize; if (attr) { update_attr(buf, src, attr, vc); @@ -113,14 +117,18 @@ static inline void bit_putcs_unaligned(struct vc_data *vc, u8 *dst) { u16 charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff; + unsigned int charcnt = vc->vc_font.charcount; u32 shift_low = 0, mod = vc->vc_font.width % 8; u32 shift_high = 8; u32 idx = vc->vc_font.width >> 3; u8 *src; while (cnt--) { - src = vc->vc_font.data + (scr_readw(s++)& - charmask)*cellsize; + u16 ch = scr_readw(s++) & charmask; + + if (ch >= charcnt) + ch = 0; + src = vc->vc_font.data + (unsigned int)ch * cellsize; if (attr) { update_attr(buf, src, attr, vc); @@ -161,6 +169,11 @@ static void bit_putcs(struct vc_data *vc, struct fb_info *info, image.height = vc->vc_font.height; image.depth = 1; + if (image.dy >= info->var.yres) + return; + + image.height = min(image.height, info->var.yres - image.dy); + if (attribute) { buf = kmalloc(cellsize, GFP_ATOMIC); if (!buf) @@ -174,6 +187,18 @@ static void bit_putcs(struct vc_data *vc, struct fb_info *info, cnt = count; image.width = vc->vc_font.width * cnt; + + if (image.dx >= info->var.xres) + break; + + if (image.dx + image.width > info->var.xres) { + image.width = info->var.xres - image.dx; + cnt = image.width / vc->vc_font.width; + if (cnt == 0) + break; + image.width = cnt * vc->vc_font.width; + } + pitch = DIV_ROUND_UP(image.width, 8) + scan_align; pitch &= ~scan_align; size = pitch * image.height + buf_align; diff --git a/fs/exec.c b/fs/exec.c index da51ca7048..2c6e61139a 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -1190,16 +1190,16 @@ static int unshare_sighand(struct task_struct *me) } /* - * These functions flushes out all traces of the currently running executable - * so that a new one can be started + * This is unlocked -- the string will always be NUL-terminated, but + * may show overlapping contents if racing concurrent reads. */ - void __set_task_comm(struct task_struct *tsk, const char *buf, bool exec) { - task_lock(tsk); + size_t len = min(strlen(buf), sizeof(tsk->comm) - 1); + trace_task_rename(tsk, buf); - strscpy_pad(tsk->comm, buf, sizeof(tsk->comm)); - task_unlock(tsk); + memcpy(tsk->comm, buf, len); + memset(&tsk->comm[len], 0, sizeof(tsk->comm) - len); perf_event_comm(tsk, exec); } diff --git a/fs/smb/client/smbdirect.c b/fs/smb/client/smbdirect.c index 754e94a0e0..6947b89247 100644 --- a/fs/smb/client/smbdirect.c +++ b/fs/smb/client/smbdirect.c @@ -457,7 +457,11 @@ static void recv_done(struct ib_cq *cq, struct ib_wc *wc) struct smbd_response *response = container_of(wc->wr_cqe, struct smbd_response, cqe); struct smbd_connection *info = response->info; - int data_length = 0; + struct smbdirect_socket *sc = &info->socket; + struct smbdirect_socket_parameters *sp = &sc->parameters; + u32 data_offset = 0; + u32 data_length = 0; + u32 remaining_data_length = 0; log_rdma_recv(INFO, "response=0x%p type=%d wc status=%d wc opcode %d byte_len=%d pkey_index=%u\n", response, response->type, wc->status, wc->opcode, @@ -489,7 +493,22 @@ static void recv_done(struct ib_cq *cq, struct ib_wc *wc) /* SMBD data transfer packet */ case SMBD_TRANSFER_DATA: data_transfer = smbd_response_payload(response); + + if (wc->byte_len < + offsetof(struct smbdirect_data_transfer, padding)) + goto error; + + remaining_data_length = le32_to_cpu(data_transfer->remaining_data_length); + data_offset = le32_to_cpu(data_transfer->data_offset); data_length = le32_to_cpu(data_transfer->data_length); + if (wc->byte_len < data_offset || + (u64)wc->byte_len < (u64)data_offset + data_length) + goto error; + + if (remaining_data_length > sp->max_fragmented_recv_size || + data_length > sp->max_fragmented_recv_size || + (u64)remaining_data_length + (u64)data_length > (u64)sp->max_fragmented_recv_size) + goto error; /* * If this is a packet with data playload place the data in diff --git a/fs/squashfs/super.c b/fs/squashfs/super.c index 22e812808e..494d21777e 100644 --- a/fs/squashfs/super.c +++ b/fs/squashfs/super.c @@ -187,10 +187,15 @@ static int squashfs_fill_super(struct super_block *sb, struct fs_context *fc) unsigned short flags; unsigned int fragments; u64 lookup_table_start, xattr_id_table_start, next_table; - int err; + int err, devblksize = sb_min_blocksize(sb, SQUASHFS_DEVBLK_SIZE); TRACE("Entered squashfs_fill_superblock\n"); + if (!devblksize) { + errorf(fc, "squashfs: unable to set blocksize\n"); + return -EINVAL; + } + sb->s_fs_info = kzalloc(sizeof(*msblk), GFP_KERNEL); if (sb->s_fs_info == NULL) { ERROR("Failed to allocate squashfs_sb_info\n"); @@ -201,7 +206,7 @@ static int squashfs_fill_super(struct super_block *sb, struct fs_context *fc) msblk->panic_on_errors = (opts->errors == Opt_errors_panic); - msblk->devblksize = sb_min_blocksize(sb, SQUASHFS_DEVBLK_SIZE); + msblk->devblksize = devblksize; msblk->devblksize_log2 = ffz(~msblk->devblksize); mutex_init(&msblk->meta_index_mutex); diff --git a/include/linux/sched.h b/include/linux/sched.h index 88aa76e84f..5f5986b0ea 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -1992,11 +1992,10 @@ static inline void kick_process(struct task_struct *tsk) { } #endif extern void __set_task_comm(struct task_struct *tsk, const char *from, bool exec); - -static inline void set_task_comm(struct task_struct *tsk, const char *from) -{ - __set_task_comm(tsk, from, false); -} +#define set_task_comm(tsk, from) ({ \ + BUILD_BUG_ON(sizeof(from) != TASK_COMM_LEN); \ + __set_task_comm(tsk, from, false); \ +}) /* * - Why not use task_lock()? diff --git a/include/net/bond_options.h b/include/net/bond_options.h index 18687ccf06..022b122a9f 100644 --- a/include/net/bond_options.h +++ b/include/net/bond_options.h @@ -77,6 +77,7 @@ enum { BOND_OPT_NS_TARGETS, BOND_OPT_PRIO, BOND_OPT_COUPLED_CONTROL, + BOND_OPT_BROADCAST_NEIGH, BOND_OPT_LAST }; diff --git a/include/net/bonding.h b/include/net/bonding.h index 95f67b308c..e06f0d63b2 100644 --- a/include/net/bonding.h +++ b/include/net/bonding.h @@ -115,6 +115,8 @@ static inline int is_netpoll_tx_blocked(struct net_device *dev) #define is_netpoll_tx_blocked(dev) (0) #endif +DECLARE_STATIC_KEY_FALSE(bond_bcast_neigh_enabled); + struct bond_params { int mode; int xmit_policy; @@ -149,6 +151,7 @@ struct bond_params { struct in6_addr ns_targets[BOND_MAX_NS_TARGETS]; #endif int coupled_control; + int broadcast_neighbor; /* 2 bytes of padding : see ether_addr_equal_64bits() */ u8 ad_actor_system[ETH_ALEN + 2]; diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h index 506ba9c80e..90c5628c14 100644 --- a/include/uapi/linux/if_link.h +++ b/include/uapi/linux/if_link.h @@ -1509,6 +1509,7 @@ enum { IFLA_BOND_MISSED_MAX, IFLA_BOND_NS_IP6_TARGET, IFLA_BOND_COUPLED_CONTROL, + IFLA_BOND_BROADCAST_NEIGH, __IFLA_BOND_MAX, }; diff --git a/io_uring/io-wq.c b/io_uring/io-wq.c index a38f36b680..5d0928f374 100644 --- a/io_uring/io-wq.c +++ b/io_uring/io-wq.c @@ -634,7 +634,7 @@ static int io_wq_worker(void *data) struct io_wq_acct *acct = io_wq_get_acct(worker); struct io_wq *wq = worker->wq; bool exit_mask = false, last_timeout = false; - char buf[TASK_COMM_LEN]; + char buf[TASK_COMM_LEN] = {}; set_mask_bits(&worker->flags, 0, BIT(IO_WORKER_F_UP) | BIT(IO_WORKER_F_RUNNING)); diff --git a/io_uring/net.c b/io_uring/net.c index 18507658a9..5275428cfc 100644 --- a/io_uring/net.c +++ b/io_uring/net.c @@ -488,6 +488,15 @@ static int io_bundle_nbufs(struct io_async_msghdr *kmsg, int ret) return nbufs; } +static int io_net_kbuf_recyle(struct io_kiocb *req, + struct io_async_msghdr *kmsg, int len) +{ + req->flags |= REQ_F_BL_NO_RECYCLE; + if (req->flags & REQ_F_BUFFERS_COMMIT) + io_kbuf_commit(req, req->buf_list, len, io_bundle_nbufs(kmsg, len)); + return -EAGAIN; +} + static inline bool io_send_finish(struct io_kiocb *req, int *ret, struct io_async_msghdr *kmsg, unsigned issue_flags) @@ -556,8 +565,7 @@ int io_sendmsg(struct io_kiocb *req, unsigned int issue_flags) kmsg->msg.msg_controllen = 0; kmsg->msg.msg_control = NULL; sr->done_io += ret; - req->flags |= REQ_F_BL_NO_RECYCLE; - return -EAGAIN; + return io_net_kbuf_recyle(req, kmsg, ret); } if (ret == -ERESTARTSYS) ret = -EINTR; @@ -654,8 +662,7 @@ retry_bundle: sr->len -= ret; sr->buf += ret; sr->done_io += ret; - req->flags |= REQ_F_BL_NO_RECYCLE; - return -EAGAIN; + return io_net_kbuf_recyle(req, kmsg, ret); } if (ret == -ERESTARTSYS) ret = -EINTR; @@ -1037,8 +1044,7 @@ retry_multishot: } if (ret > 0 && io_net_retry(sock, flags)) { sr->done_io += ret; - req->flags |= REQ_F_BL_NO_RECYCLE; - return -EAGAIN; + return io_net_kbuf_recyle(req, kmsg, ret); } if (ret == -ERESTARTSYS) ret = -EINTR; @@ -1177,8 +1183,7 @@ retry_multishot: sr->len -= ret; sr->buf += ret; sr->done_io += ret; - req->flags |= REQ_F_BL_NO_RECYCLE; - return -EAGAIN; + return io_net_kbuf_recyle(req, kmsg, ret); } if (ret == -ERESTARTSYS) ret = -EINTR; @@ -1406,8 +1411,7 @@ int io_send_zc(struct io_kiocb *req, unsigned int issue_flags) zc->len -= ret; zc->buf += ret; zc->done_io += ret; - req->flags |= REQ_F_BL_NO_RECYCLE; - return -EAGAIN; + return io_net_kbuf_recyle(req, kmsg, ret); } if (ret == -ERESTARTSYS) ret = -EINTR; @@ -1466,8 +1470,7 @@ int io_sendmsg_zc(struct io_kiocb *req, unsigned int issue_flags) if (ret > 0 && io_net_retry(sock, flags)) { sr->done_io += ret; - req->flags |= REQ_F_BL_NO_RECYCLE; - return -EAGAIN; + return io_net_kbuf_recyle(req, kmsg, ret); } if (ret == -ERESTARTSYS) ret = -EINTR; diff --git a/io_uring/sqpoll.c b/io_uring/sqpoll.c index a791dd476a..fa61685df1 100644 --- a/io_uring/sqpoll.c +++ b/io_uring/sqpoll.c @@ -271,7 +271,7 @@ static int io_sq_thread(void *data) struct io_ring_ctx *ctx; struct rusage start; unsigned long timeout = 0; - char buf[TASK_COMM_LEN]; + char buf[TASK_COMM_LEN] = {}; DEFINE_WAIT(wait); /* offload context creation failed, just exit */ diff --git a/kernel/kthread.c b/kernel/kthread.c index df4f283839..ed586b9e31 100644 --- a/kernel/kthread.c +++ b/kernel/kthread.c @@ -817,10 +817,11 @@ EXPORT_SYMBOL(kthread_stop_put); int kthreadd(void *unused) { + static const char comm[TASK_COMM_LEN] = "kthreadd"; struct task_struct *tsk = current; /* Setup a clean context for our children to inherit. */ - set_task_comm(tsk, "kthreadd"); + set_task_comm(tsk, comm); ignore_signals(tsk); set_cpus_allowed_ptr(tsk, housekeeping_cpumask(HK_TYPE_KTHREAD)); set_mems_allowed(node_states[N_MEMORY]); diff --git a/lib/buildid.c b/lib/buildid.c index c4b0f376fb..a80592ddaf 100644 --- a/lib/buildid.c +++ b/lib/buildid.c @@ -5,6 +5,7 @@ #include #include #include +#include #include #define BUILD_ID 3 @@ -65,20 +66,9 @@ static int freader_get_folio(struct freader *r, loff_t file_off) freader_put_folio(r); - /* reject secretmem folios created with memfd_secret() */ - if (secretmem_mapping(r->file->f_mapping)) - return -EFAULT; - + /* only use page cache lookup - fail if not already cached */ r->folio = filemap_get_folio(r->file->f_mapping, file_off >> PAGE_SHIFT); - /* if sleeping is allowed, wait for the page, if necessary */ - if (r->may_fault && (IS_ERR(r->folio) || !folio_test_uptodate(r->folio))) { - filemap_invalidate_lock_shared(r->file->f_mapping); - r->folio = read_cache_folio(r->file->f_mapping, file_off >> PAGE_SHIFT, - NULL, r->file); - filemap_invalidate_unlock_shared(r->file->f_mapping); - } - if (IS_ERR(r->folio) || !folio_test_uptodate(r->folio)) { if (!IS_ERR(r->folio)) folio_put(r->folio); @@ -116,6 +106,24 @@ static const void *freader_fetch(struct freader *r, loff_t file_off, size_t sz) return r->data + file_off; } + /* reject secretmem folios created with memfd_secret() */ + if (secretmem_mapping(r->file->f_mapping)) { + r->err = -EFAULT; + return NULL; + } + + /* use __kernel_read() for sleepable context */ + if (r->may_fault) { + ssize_t ret; + + ret = __kernel_read(r->file, r->buf, sz, &file_off); + if (ret != sz) { + r->err = (ret < 0) ? ret : -EIO; + return NULL; + } + return r->buf; + } + /* fetch or reuse folio for given file offset */ r->err = freader_get_folio(r, file_off); if (r->err) diff --git a/net/mptcp/ctrl.c b/net/mptcp/ctrl.c index bdcc4136e9..c70e8a780a 100644 --- a/net/mptcp/ctrl.c +++ b/net/mptcp/ctrl.c @@ -381,10 +381,15 @@ void mptcp_active_enable(struct sock *sk) struct mptcp_pernet *pernet = mptcp_get_pernet(sock_net(sk)); if (atomic_read(&pernet->active_disable_times)) { - struct dst_entry *dst = sk_dst_get(sk); + struct net_device *dev; + struct dst_entry *dst; - if (dst && dst->dev && (dst->dev->flags & IFF_LOOPBACK)) + rcu_read_lock(); + dst = __sk_dst_get(sk); + dev = dst ? dst_dev_rcu(dst) : NULL; + if (dev && (dev->flags & IFF_LOOPBACK)) atomic_set(&pernet->active_disable_times, 0); + rcu_read_unlock(); } } diff --git a/net/sunrpc/xprtrdma/svc_rdma_rw.c b/net/sunrpc/xprtrdma/svc_rdma_rw.c index 661b3fe277..945fbb3743 100644 --- a/net/sunrpc/xprtrdma/svc_rdma_rw.c +++ b/net/sunrpc/xprtrdma/svc_rdma_rw.c @@ -848,7 +848,7 @@ static int svc_rdma_copy_inline_range(struct svc_rqst *rqstp, head->rc_page_count++; dst = page_address(rqstp->rq_pages[head->rc_curpage]); - memcpy(dst + head->rc_curpage, src + offset, page_len); + memcpy((unsigned char *)dst + head->rc_pageoff, src + offset, page_len); head->rc_readbytes += page_len; head->rc_pageoff += page_len; diff --git a/net/vmw_vsock/vmci_transport.c b/net/vmw_vsock/vmci_transport.c index b370070194..7eccd6708d 100644 --- a/net/vmw_vsock/vmci_transport.c +++ b/net/vmw_vsock/vmci_transport.c @@ -119,6 +119,8 @@ vmci_transport_packet_init(struct vmci_transport_packet *pkt, u16 proto, struct vmci_handle handle) { + memset(pkt, 0, sizeof(*pkt)); + /* We register the stream control handler as an any cid handle so we * must always send from a source address of VMADDR_CID_ANY */ @@ -131,8 +133,6 @@ vmci_transport_packet_init(struct vmci_transport_packet *pkt, pkt->type = type; pkt->src_port = src->svm_port; pkt->dst_port = dst->svm_port; - memset(&pkt->proto, 0, sizeof(pkt->proto)); - memset(&pkt->_reserved2, 0, sizeof(pkt->_reserved2)); switch (pkt->type) { case VMCI_TRANSPORT_PACKET_TYPE_INVALID: diff --git a/redhat/kernel.changelog-10.1 b/redhat/kernel.changelog-10.1 index f0e60c613d..0fdd00f5a8 100644 --- a/redhat/kernel.changelog-10.1 +++ b/redhat/kernel.changelog-10.1 @@ -1,3 +1,32 @@ +* Sat Jan 31 2026 CKI KWF Bot [6.12.0-124.35.1.el10_1] +- ice: Fix kernel panic due to page refcount underflow (CKI Backport Bot) [RHEL-139734] +- mptcp: Use __sk_dst_get() and dst_dev_rcu() in mptcp_active_enable(). (Davide Caratti) [RHEL-129044] {CVE-2025-40133} +- mptcp: Call dst_release() in mptcp_active_enable(). (Davide Caratti) [RHEL-129044] +- vsock/vmci: Clear the vmci transport packet properly when initializing it (CKI Backport Bot) [RHEL-137703] {CVE-2025-38403} +Resolves: RHEL-129044, RHEL-137703, RHEL-139734 + +* Thu Jan 29 2026 CKI KWF Bot [6.12.0-124.34.1.el10_1] +- ice: prevent NULL deref in ice_lag_move_new_vf_nodes() (Michal Schmidt) [RHEL-143255] +- svcrdma: use rc_pageoff for memcpy byte offset (CKI Backport Bot) [RHEL-142793] {CVE-2025-68811} +- exec: Make sure task->comm is always NUL-terminated (Luiz Capitulino) [RHEL-141711] +- lib/buildid: use __kernel_read() for sleepable context (Waiman Long) [RHEL-141229] +- net: bonding: update the slave array for broadcast mode (Hangbin Liu) [RHEL-138325] +- net: bonding: add broadcast_neighbor netlink option (Hangbin Liu) [RHEL-138325] +- net: bonding: add broadcast_neighbor option for 802.3ad (Hangbin Liu) [RHEL-138325] +Resolves: RHEL-138325, RHEL-141229, RHEL-141711, RHEL-142793, RHEL-143255 + +* Tue Jan 27 2026 Julio Faracco [6.12.0-124.33.1.el10_1] +- io_uring/net: commit partial buffers on retry (Jeff Moyer) [RHEL-137333] {CVE-2025-38730} +- smb: client: let recv_done verify data_offset, data_length and remaining_data_length (Paulo Alcantara) [RHEL-131394] {CVE-2025-39933} +Resolves: RHEL-131394, RHEL-137333 + +* Sat Jan 24 2026 CKI KWF Bot [6.12.0-124.32.1.el10_1] +- squashfs: fix memory leak in squashfs_fill_super (Abhi Das) [RHEL-138024] {CVE-2025-38415} +- Squashfs: check return result of sb_min_blocksize (CKI Backport Bot) [RHEL-138024] {CVE-2025-38415} +- fbdev: Add bounds checking in bit_putcs to fix vmalloc-out-of-bounds (CKI Backport Bot) [RHEL-137686] {CVE-2025-40304} +- fbdev: bitblit: bound-check glyph index in bit_putcs* (CKI Backport Bot) [RHEL-136945] {CVE-2025-40322} +Resolves: RHEL-136945, RHEL-137686, RHEL-138024 + * Thu Jan 22 2026 CKI KWF Bot [6.12.0-124.31.1.el10_1] - i40e: support generic devlink param "max_mac_per_vf" (Mohammad Heib) [RHEL-121647] - devlink: Add new "max_mac_per_vf" generic device param (Mohammad Heib) [RHEL-121647] @@ -19,6 +48,7 @@ - RDMA/core: Fix "KASAN: slab-use-after-free Read in ib_register_device" problem (CKI Backport Bot) [RHEL-134363] {CVE-2025-38022} - uprobes: Fix race in uprobe_free_utask (Jay Shin) [RHEL-133456] - ASoC: Intel: bytcr_rt5640: Fix invalid quirk input mapping (CKI Backport Bot) [RHEL-129115] {CVE-2025-40154} +- kabi: stabilize struct alt_instr (Čestmír Kalina) [RHEL-122759] Resolves: RHEL-121647, RHEL-122759, RHEL-126599, RHEL-129115, RHEL-129452, RHEL-133336, RHEL-133456, RHEL-134363, RHEL-134763, RHEL-136289 * Wed Jan 21 2026 CKI KWF Bot [6.12.0-124.30.1.el10_1] diff --git a/uki-addons.sbat b/uki-addons.sbat index 53abc87f3e..fbd6978dc0 100644 --- a/uki-addons.sbat +++ b/uki-addons.sbat @@ -1,3 +1,3 @@ sbat,1,SBAT Version,sbat,1,https://github.com/rhboot/shim/blob/main/SBAT.md -kernel-uki-virt-addons.centos,1,Red Hat,kernel-uki-virt-addons,6.12.0-124.31.1.el10.x86_64,mailto:secalert@redhat.com -kernel-uki-virt-addons.almalinux,1,AlmaLinux,kernel-uki-virt-addons,6.12.0-124.31.1.el10.x86_64,mailto:security@almalinux.org +kernel-uki-virt-addons.centos,1,Red Hat,kernel-uki-virt-addons,6.12.0-124.35.1.el10.x86_64,mailto:secalert@redhat.com +kernel-uki-virt-addons.almalinux,1,AlmaLinux,kernel-uki-virt-addons,6.12.0-124.35.1.el10.x86_64,mailto:security@almalinux.org diff --git a/uki.sbat b/uki.sbat index 57fe8fe596..83e6499cc9 100644 --- a/uki.sbat +++ b/uki.sbat @@ -1,3 +1,3 @@ sbat,1,SBAT Version,sbat,1,https://github.com/rhboot/shim/blob/main/SBAT.md -kernel-uki-virt.centos,1,Red Hat,kernel-uki-virt,6.12.0-124.31.1.el10.x86_64,mailto:secalert@redhat.com -kernel-uki-virt.almalinux,1,AlmaLinux,kernel-uki-virt,6.12.0-124.31.1.el10.x86_64,mailto:security@almalinux.org +kernel-uki-virt.centos,1,Red Hat,kernel-uki-virt,6.12.0-124.35.1.el10.x86_64,mailto:secalert@redhat.com +kernel-uki-virt.almalinux,1,AlmaLinux,kernel-uki-virt,6.12.0-124.35.1.el10.x86_64,mailto:security@almalinux.org