Import of kernel-4.18.0-553.134.1.el8_10

This commit is contained in:
almalinux-bot-kernel 2026-06-18 05:41:14 +00:00
parent 1f10fa954f
commit a8926071b0
14 changed files with 188 additions and 84 deletions

View File

@ -12,7 +12,7 @@ RHEL_MINOR = 10
#
# Use this spot to avoid future merge conflicts.
# Do not trim this comment.
RHEL_RELEASE = 553.132.1
RHEL_RELEASE = 553.134.1
#
# ZSTREAM

View File

@ -151,6 +151,11 @@ static void brcmf_fweh_handle_if_event(struct brcmf_pub *drvr,
bphy_err(drvr, "invalid interface index: %u\n", ifevent->ifidx);
return;
}
if (ifevent->bsscfgidx >= BRCMF_MAX_IFS) {
bphy_err(drvr, "invalid bsscfg index: %u\n",
ifevent->bsscfgidx);
return;
}
ifp = drvr->iflist[ifevent->bsscfgidx];

View File

@ -933,6 +933,12 @@ static void privcmd_close(struct vm_area_struct *vma)
kfree(pages);
}
static int privcmd_may_split(struct vm_area_struct *area, unsigned long addr)
{
/* Forbid splitting, avoids double free via privcmd_close(). */
return -EINVAL;
}
static vm_fault_t privcmd_fault(struct vm_fault *vmf)
{
printk(KERN_DEBUG "privcmd_fault: vma=%p %lx-%lx, pgoff=%lx, uv=%p\n",
@ -944,6 +950,7 @@ static vm_fault_t privcmd_fault(struct vm_fault *vmf)
static const struct vm_operations_struct privcmd_vm_ops = {
.close = privcmd_close,
.split = privcmd_may_split,
.fault = privcmd_fault
};

View File

@ -367,6 +367,8 @@ static ssize_t buildid_show(struct hyp_sysfs_attr *attr, char *buffer)
ret = sprintf(buffer, "<denied>");
return ret;
}
if (ret > PAGE_SIZE)
return -ENOSPC;
buildid = kmalloc(sizeof(*buildid) + ret, GFP_KERNEL);
if (!buildid)
@ -374,8 +376,10 @@ static ssize_t buildid_show(struct hyp_sysfs_attr *attr, char *buffer)
buildid->len = ret;
ret = HYPERVISOR_xen_version(XENVER_build_id, buildid);
if (ret > 0)
ret = sprintf(buffer, "%s", buildid->buf);
if (ret > 0) {
/* Build id is binary, not a string. */
memcpy(buffer, buildid->buf, ret);
}
kfree(buildid);
return ret;

View File

@ -67,6 +67,16 @@ struct nft_flow_rule {
struct flow_rule *rule;
};
static inline struct flow_action_entry *
nft_flow_action_entry_next(struct nft_offload_ctx *ctx,
struct nft_flow_rule *flow)
{
if (unlikely(ctx->num_actions >= flow->rule->action.num_entries))
return NULL;
return &flow->rule->action.entries[ctx->num_actions++];
}
void nft_flow_rule_set_addr_type(struct nft_flow_rule *flow,
enum flow_dissector_key_id addr_type);

View File

@ -5367,9 +5367,11 @@ static void hci_user_passkey_notify_evt(struct hci_dev *hdev, void *data,
bt_dev_dbg(hdev, "");
hci_dev_lock(hdev);
conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
if (!conn)
return;
goto unlock;
conn->passkey_notify = __le32_to_cpu(ev->passkey);
conn->passkey_entered = 0;
@ -5378,6 +5380,9 @@ static void hci_user_passkey_notify_evt(struct hci_dev *hdev, void *data,
mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
conn->dst_type, conn->passkey_notify,
conn->passkey_entered);
unlock:
hci_dev_unlock(hdev);
}
static void hci_keypress_notify_evt(struct hci_dev *hdev, void *data,
@ -5388,14 +5393,16 @@ static void hci_keypress_notify_evt(struct hci_dev *hdev, void *data,
bt_dev_dbg(hdev, "");
hci_dev_lock(hdev);
conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
if (!conn)
return;
goto unlock;
switch (ev->type) {
case HCI_KEYPRESS_STARTED:
conn->passkey_entered = 0;
return;
goto unlock;
case HCI_KEYPRESS_ENTERED:
conn->passkey_entered++;
@ -5410,13 +5417,16 @@ static void hci_keypress_notify_evt(struct hci_dev *hdev, void *data,
break;
case HCI_KEYPRESS_COMPLETED:
return;
goto unlock;
}
if (hci_dev_test_flag(hdev, HCI_MGMT))
mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
conn->dst_type, conn->passkey_notify,
conn->passkey_entered);
unlock:
hci_dev_unlock(hdev);
}
static void hci_simple_pair_complete_evt(struct hci_dev *hdev, void *data,

View File

@ -6615,7 +6615,7 @@ static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata,
struct ieee80211_bss *bss = (void *)cbss->priv;
struct sta_info *new_sta = NULL;
struct ieee80211_link_data *link;
bool have_sta = false;
struct sta_info *have_sta = NULL;
bool mlo;
int err;
@ -6653,11 +6653,8 @@ static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata,
goto out_err;
}
if (assoc) {
rcu_read_lock();
if (assoc)
have_sta = sta_info_get(sdata, ap_mld_addr);
rcu_read_unlock();
}
if (!have_sta) {
if (mlo)
@ -6780,6 +6777,8 @@ static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata,
out_err:
ieee80211_link_release_channel(&sdata->deflink);
if (mlo && have_sta)
WARN_ON(__sta_info_destroy(have_sta));
ieee80211_vif_set_links(sdata, 0);
return err;
}

View File

@ -4774,7 +4774,7 @@ static bool ieee80211_invoke_fast_rx(struct ieee80211_rx_data *rx,
struct sk_buff *skb = rx->skb;
struct ieee80211_hdr *hdr = (void *)skb->data;
struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
static ieee80211_rx_result res;
ieee80211_rx_result res;
int orig_len = skb->len;
int hdrlen = ieee80211_hdrlen(hdr->frame_control);
int snap_offs = hdrlen;

View File

@ -3714,6 +3714,8 @@ int __init mptcp_proto_v6_init(void)
{
int err;
mptcp_subflow_v6_init();
mptcp_v6_prot = mptcp_prot;
strcpy(mptcp_v6_prot.name, "MPTCPv6");
mptcp_v6_prot.slab = NULL;

View File

@ -603,6 +603,7 @@ static inline void mptcp_subflow_tcp_fallback(struct sock *sk,
void __init mptcp_proto_init(void);
#if IS_ENABLED(CONFIG_MPTCP_IPV6)
int __init mptcp_proto_v6_init(void);
void __init mptcp_subflow_v6_init(void);
#endif
struct sock *mptcp_sk_clone(const struct sock *sk,

View File

@ -1766,7 +1766,15 @@ void __init mptcp_subflow_init(void)
tcp_prot_override = tcp_prot;
tcp_prot_override.release_cb = tcp_release_cb_override;
mptcp_diag_subflow_init(&subflow_ulp_ops);
if (tcp_register_ulp(&subflow_ulp_ops) != 0)
panic("MPTCP: failed to register subflows to ULP\n");
}
#if IS_ENABLED(CONFIG_MPTCP_IPV6)
void __init mptcp_subflow_v6_init(void)
{
subflow_request_sock_ipv6_ops = tcp_request_sock_ipv6_ops;
subflow_request_sock_ipv6_ops.route_req = subflow_v6_route_req;
@ -1784,10 +1792,5 @@ void __init mptcp_subflow_init(void)
tcpv6_prot_override = tcpv6_prot;
tcpv6_prot_override.release_cb = tcp_release_cb_override;
#endif
mptcp_diag_subflow_init(&subflow_ulp_ops);
if (tcp_register_ulp(&subflow_ulp_ops) != 0)
panic("MPTCP: failed to register subflows to ULP\n");
}
#endif

View File

@ -67,7 +67,10 @@ int nft_fwd_dup_netdev_offload(struct nft_offload_ctx *ctx,
if (!dev)
return -EOPNOTSUPP;
entry = &flow->rule->action.entries[ctx->num_actions++];
entry = nft_flow_action_entry_next(ctx, flow);
if (!entry)
return -E2BIG;
entry->id = id;
entry->dev = dev;

View File

@ -13,6 +13,8 @@
#include <net/netfilter/nf_conntrack_core.h>
#include <net/netfilter/nf_conntrack_tuple.h>
#define NF_FLOW_RULE_ACTION_MAX 24
static struct workqueue_struct *nf_flow_offload_add_wq;
static struct workqueue_struct *nf_flow_offload_del_wq;
static struct workqueue_struct *nf_flow_offload_stats_wq;
@ -167,7 +169,12 @@ static void flow_offload_mangle(struct flow_action_entry *entry,
static inline struct flow_action_entry *
flow_action_entry_next(struct nf_flow_rule *flow_rule)
{
int i = flow_rule->rule->action.num_entries++;
int i;
if (unlikely(flow_rule->rule->action.num_entries >= NF_FLOW_RULE_ACTION_MAX))
return NULL;
i = flow_rule->rule->action.num_entries++;
return &flow_rule->rule->action.entries[i];
}
@ -184,6 +191,9 @@ static int flow_offload_eth_src(struct net *net,
u32 mask, val;
u16 val16;
if (!entry0 || !entry1)
return -E2BIG;
dev = dev_get_by_index(net, tuple->iifidx);
if (!dev)
return -ENOENT;
@ -218,6 +228,9 @@ static int flow_offload_eth_dst(struct net *net,
u8 nud_state;
u16 val16;
if (!entry0 || !entry1)
return -E2BIG;
dst_cache = flow->tuplehash[dir].tuple.dst_cache;
n = dst_neigh_lookup(dst_cache, daddr);
if (!n)
@ -248,16 +261,19 @@ static int flow_offload_eth_dst(struct net *net,
return 0;
}
static void flow_offload_ipv4_snat(struct net *net,
const struct flow_offload *flow,
enum flow_offload_tuple_dir dir,
struct nf_flow_rule *flow_rule)
static int flow_offload_ipv4_snat(struct net *net,
const struct flow_offload *flow,
enum flow_offload_tuple_dir dir,
struct nf_flow_rule *flow_rule)
{
struct flow_action_entry *entry = flow_action_entry_next(flow_rule);
u32 mask = ~htonl(0xffffffff);
__be32 addr;
u32 offset;
if (!entry)
return -E2BIG;
switch (dir) {
case FLOW_OFFLOAD_DIR_ORIGINAL:
addr = flow->tuplehash[FLOW_OFFLOAD_DIR_REPLY].tuple.dst_v4.s_addr;
@ -268,23 +284,27 @@ static void flow_offload_ipv4_snat(struct net *net,
offset = offsetof(struct iphdr, daddr);
break;
default:
return;
return -EOPNOTSUPP;
}
flow_offload_mangle(entry, FLOW_ACT_MANGLE_HDR_TYPE_IP4, offset,
&addr, &mask);
return 0;
}
static void flow_offload_ipv4_dnat(struct net *net,
const struct flow_offload *flow,
enum flow_offload_tuple_dir dir,
struct nf_flow_rule *flow_rule)
static int flow_offload_ipv4_dnat(struct net *net,
const struct flow_offload *flow,
enum flow_offload_tuple_dir dir,
struct nf_flow_rule *flow_rule)
{
struct flow_action_entry *entry = flow_action_entry_next(flow_rule);
u32 mask = ~htonl(0xffffffff);
__be32 addr;
u32 offset;
if (!entry)
return -E2BIG;
switch (dir) {
case FLOW_OFFLOAD_DIR_ORIGINAL:
addr = flow->tuplehash[FLOW_OFFLOAD_DIR_REPLY].tuple.src_v4.s_addr;
@ -295,14 +315,15 @@ static void flow_offload_ipv4_dnat(struct net *net,
offset = offsetof(struct iphdr, saddr);
break;
default:
return;
return -EOPNOTSUPP;
}
flow_offload_mangle(entry, FLOW_ACT_MANGLE_HDR_TYPE_IP4, offset,
&addr, &mask);
return 0;
}
static void flow_offload_ipv6_mangle(struct nf_flow_rule *flow_rule,
static int flow_offload_ipv6_mangle(struct nf_flow_rule *flow_rule,
unsigned int offset,
const __be32 *addr, const __be32 *mask)
{
@ -311,15 +332,20 @@ static void flow_offload_ipv6_mangle(struct nf_flow_rule *flow_rule,
for (i = 0; i < sizeof(struct in6_addr) / sizeof(u32); i++) {
entry = flow_action_entry_next(flow_rule);
if (!entry)
return -E2BIG;
flow_offload_mangle(entry, FLOW_ACT_MANGLE_HDR_TYPE_IP6,
offset + i * sizeof(u32), &addr[i], mask);
}
return 0;
}
static void flow_offload_ipv6_snat(struct net *net,
const struct flow_offload *flow,
enum flow_offload_tuple_dir dir,
struct nf_flow_rule *flow_rule)
static int flow_offload_ipv6_snat(struct net *net,
const struct flow_offload *flow,
enum flow_offload_tuple_dir dir,
struct nf_flow_rule *flow_rule)
{
u32 mask = ~htonl(0xffffffff);
const __be32 *addr;
@ -335,16 +361,16 @@ static void flow_offload_ipv6_snat(struct net *net,
offset = offsetof(struct ipv6hdr, daddr);
break;
default:
return;
return -EOPNOTSUPP;
}
flow_offload_ipv6_mangle(flow_rule, offset, addr, &mask);
return flow_offload_ipv6_mangle(flow_rule, offset, addr, &mask);
}
static void flow_offload_ipv6_dnat(struct net *net,
const struct flow_offload *flow,
enum flow_offload_tuple_dir dir,
struct nf_flow_rule *flow_rule)
static int flow_offload_ipv6_dnat(struct net *net,
const struct flow_offload *flow,
enum flow_offload_tuple_dir dir,
struct nf_flow_rule *flow_rule)
{
u32 mask = ~htonl(0xffffffff);
const __be32 *addr;
@ -360,10 +386,10 @@ static void flow_offload_ipv6_dnat(struct net *net,
offset = offsetof(struct ipv6hdr, saddr);
break;
default:
return;
return -EOPNOTSUPP;
}
flow_offload_ipv6_mangle(flow_rule, offset, addr, &mask);
return flow_offload_ipv6_mangle(flow_rule, offset, addr, &mask);
}
static int flow_offload_l4proto(const struct flow_offload *flow)
@ -385,15 +411,18 @@ static int flow_offload_l4proto(const struct flow_offload *flow)
return type;
}
static void flow_offload_port_snat(struct net *net,
const struct flow_offload *flow,
enum flow_offload_tuple_dir dir,
struct nf_flow_rule *flow_rule)
static int flow_offload_port_snat(struct net *net,
const struct flow_offload *flow,
enum flow_offload_tuple_dir dir,
struct nf_flow_rule *flow_rule)
{
struct flow_action_entry *entry = flow_action_entry_next(flow_rule);
u32 mask, port;
u32 offset;
if (!entry)
return -E2BIG;
switch (dir) {
case FLOW_OFFLOAD_DIR_ORIGINAL:
port = ntohs(flow->tuplehash[FLOW_OFFLOAD_DIR_REPLY].tuple.dst_port);
@ -408,22 +437,26 @@ static void flow_offload_port_snat(struct net *net,
mask = ~htonl(0xffff);
break;
default:
return;
return -EOPNOTSUPP;
}
flow_offload_mangle(entry, flow_offload_l4proto(flow), offset,
&port, &mask);
return 0;
}
static void flow_offload_port_dnat(struct net *net,
const struct flow_offload *flow,
enum flow_offload_tuple_dir dir,
struct nf_flow_rule *flow_rule)
static int flow_offload_port_dnat(struct net *net,
const struct flow_offload *flow,
enum flow_offload_tuple_dir dir,
struct nf_flow_rule *flow_rule)
{
struct flow_action_entry *entry = flow_action_entry_next(flow_rule);
u32 mask, port;
u32 offset;
if (!entry)
return -E2BIG;
switch (dir) {
case FLOW_OFFLOAD_DIR_ORIGINAL:
port = ntohs(flow->tuplehash[FLOW_OFFLOAD_DIR_REPLY].tuple.src_port);
@ -438,20 +471,24 @@ static void flow_offload_port_dnat(struct net *net,
mask = ~htonl(0xffff0000);
break;
default:
return;
return -EOPNOTSUPP;
}
flow_offload_mangle(entry, flow_offload_l4proto(flow), offset,
&port, &mask);
return 0;
}
static void flow_offload_ipv4_checksum(struct net *net,
const struct flow_offload *flow,
struct nf_flow_rule *flow_rule)
static int flow_offload_ipv4_checksum(struct net *net,
const struct flow_offload *flow,
struct nf_flow_rule *flow_rule)
{
u8 protonum = flow->tuplehash[FLOW_OFFLOAD_DIR_ORIGINAL].tuple.l4proto;
struct flow_action_entry *entry = flow_action_entry_next(flow_rule);
if (!entry)
return -E2BIG;
entry->id = FLOW_ACTION_CSUM;
entry->csum_flags = TCA_CSUM_UPDATE_FLAG_IPV4HDR;
@ -463,24 +500,30 @@ static void flow_offload_ipv4_checksum(struct net *net,
entry->csum_flags |= TCA_CSUM_UPDATE_FLAG_UDP;
break;
}
return 0;
}
static void flow_offload_redirect(const struct flow_offload *flow,
enum flow_offload_tuple_dir dir,
struct nf_flow_rule *flow_rule)
static int flow_offload_redirect(const struct flow_offload *flow,
enum flow_offload_tuple_dir dir,
struct nf_flow_rule *flow_rule)
{
struct flow_action_entry *entry = flow_action_entry_next(flow_rule);
struct rtable *rt;
if (!entry)
return -E2BIG;
rt = (struct rtable *)flow->tuplehash[dir].tuple.dst_cache;
entry->id = FLOW_ACTION_REDIRECT;
entry->dev = rt->dst.dev;
dev_hold(rt->dst.dev);
return 0;
}
static void flow_offload_encap_tunnel(const struct flow_offload *flow,
enum flow_offload_tuple_dir dir,
struct nf_flow_rule *flow_rule)
static int flow_offload_encap_tunnel(const struct flow_offload *flow,
enum flow_offload_tuple_dir dir,
struct nf_flow_rule *flow_rule)
{
struct flow_action_entry *entry;
struct dst_entry *dst;
@ -492,15 +535,19 @@ static void flow_offload_encap_tunnel(const struct flow_offload *flow,
tun_info = lwt_tun_info(dst->lwtstate);
if (tun_info && (tun_info->mode & IP_TUNNEL_INFO_TX)) {
entry = flow_action_entry_next(flow_rule);
if (!entry)
return -E2BIG;
entry->id = FLOW_ACTION_TUNNEL_ENCAP;
entry->tunnel = tun_info;
}
}
return 0;
}
static void flow_offload_decap_tunnel(const struct flow_offload *flow,
enum flow_offload_tuple_dir dir,
struct nf_flow_rule *flow_rule)
static int flow_offload_decap_tunnel(const struct flow_offload *flow,
enum flow_offload_tuple_dir dir,
struct nf_flow_rule *flow_rule)
{
struct flow_action_entry *entry;
struct dst_entry *dst;
@ -512,35 +559,44 @@ static void flow_offload_decap_tunnel(const struct flow_offload *flow,
tun_info = lwt_tun_info(dst->lwtstate);
if (tun_info && (tun_info->mode & IP_TUNNEL_INFO_TX)) {
entry = flow_action_entry_next(flow_rule);
if (!entry)
return -E2BIG;
entry->id = FLOW_ACTION_TUNNEL_DECAP;
}
}
return 0;
}
int nf_flow_rule_route_ipv4(struct net *net, struct flow_offload *flow,
enum flow_offload_tuple_dir dir,
struct nf_flow_rule *flow_rule)
{
flow_offload_decap_tunnel(flow, dir, flow_rule);
flow_offload_encap_tunnel(flow, dir, flow_rule);
if (flow_offload_decap_tunnel(flow, dir, flow_rule) < 0 ||
flow_offload_encap_tunnel(flow, dir, flow_rule) < 0)
return -1;
if (flow_offload_eth_src(net, flow, dir, flow_rule) < 0 ||
flow_offload_eth_dst(net, flow, dir, flow_rule) < 0)
return -1;
if (test_bit(NF_FLOW_SNAT, &flow->flags)) {
flow_offload_ipv4_snat(net, flow, dir, flow_rule);
flow_offload_port_snat(net, flow, dir, flow_rule);
if (flow_offload_ipv4_snat(net, flow, dir, flow_rule) < 0 ||
flow_offload_port_snat(net, flow, dir, flow_rule) < 0)
return -1;
}
if (test_bit(NF_FLOW_DNAT, &flow->flags)) {
flow_offload_ipv4_dnat(net, flow, dir, flow_rule);
flow_offload_port_dnat(net, flow, dir, flow_rule);
if (flow_offload_ipv4_dnat(net, flow, dir, flow_rule) < 0 ||
flow_offload_port_dnat(net, flow, dir, flow_rule) < 0)
return -1;
}
if (test_bit(NF_FLOW_SNAT, &flow->flags) ||
test_bit(NF_FLOW_DNAT, &flow->flags))
flow_offload_ipv4_checksum(net, flow, flow_rule);
if (flow_offload_ipv4_checksum(net, flow, flow_rule) < 0)
return -1;
flow_offload_redirect(flow, dir, flow_rule);
if (flow_offload_redirect(flow, dir, flow_rule) < 0)
return -1;
return 0;
}
@ -550,30 +606,32 @@ int nf_flow_rule_route_ipv6(struct net *net, struct flow_offload *flow,
enum flow_offload_tuple_dir dir,
struct nf_flow_rule *flow_rule)
{
flow_offload_decap_tunnel(flow, dir, flow_rule);
flow_offload_encap_tunnel(flow, dir, flow_rule);
if (flow_offload_decap_tunnel(flow, dir, flow_rule) < 0 ||
flow_offload_encap_tunnel(flow, dir, flow_rule) < 0)
return -1;
if (flow_offload_eth_src(net, flow, dir, flow_rule) < 0 ||
flow_offload_eth_dst(net, flow, dir, flow_rule) < 0)
return -1;
if (test_bit(NF_FLOW_SNAT, &flow->flags)) {
flow_offload_ipv6_snat(net, flow, dir, flow_rule);
flow_offload_port_snat(net, flow, dir, flow_rule);
if (flow_offload_ipv6_snat(net, flow, dir, flow_rule) < 0 ||
flow_offload_port_snat(net, flow, dir, flow_rule) < 0)
return -1;
}
if (test_bit(NF_FLOW_DNAT, &flow->flags)) {
flow_offload_ipv6_dnat(net, flow, dir, flow_rule);
flow_offload_port_dnat(net, flow, dir, flow_rule);
if (flow_offload_ipv6_dnat(net, flow, dir, flow_rule) < 0 ||
flow_offload_port_dnat(net, flow, dir, flow_rule) < 0)
return -1;
}
flow_offload_redirect(flow, dir, flow_rule);
if (flow_offload_redirect(flow, dir, flow_rule) < 0)
return -1;
return 0;
}
EXPORT_SYMBOL_GPL(nf_flow_rule_route_ipv6);
#define NF_FLOW_RULE_ACTION_MAX 16
static struct nf_flow_rule *
nf_flow_offload_rule_alloc(struct net *net,
const struct flow_offload_work *offload,

View File

@ -135,7 +135,9 @@ static int nft_immediate_offload_verdict(struct nft_offload_ctx *ctx,
struct flow_action_entry *entry;
const struct nft_data *data;
entry = &flow->rule->action.entries[ctx->num_actions++];
entry = nft_flow_action_entry_next(ctx, flow);
if (!entry)
return -E2BIG;
data = &priv->data;
switch (data->verdict.code) {