From 6bf71a44d3688c94c2cfcdd693ef09e46d8ff72a Mon Sep 17 00:00:00 2001 From: almalinux-bot-kernel Date: Fri, 5 Jun 2026 05:37:07 +0000 Subject: [PATCH] Import of kernel-4.18.0-553.129.1.el8_10 --- Makefile.rhelver | 2 +- drivers/block/nbd.c | 3 +- drivers/net/geneve.c | 16 +------ fs/cifs/smb2ops.c | 85 ++++++++++++++++++++++++++--------- fs/cifs/smb2pdu.h | 5 ++- net/ceph/messenger_v2.c | 2 + net/ceph/osdmap.c | 4 +- net/netfilter/nf_tables_api.c | 1 + net/smc/af_smc.c | 11 +++++ 9 files changed, 90 insertions(+), 39 deletions(-) diff --git a/Makefile.rhelver b/Makefile.rhelver index b57fcbc8b6..767e830e08 100644 --- a/Makefile.rhelver +++ b/Makefile.rhelver @@ -12,7 +12,7 @@ RHEL_MINOR = 10 # # Use this spot to avoid future merge conflicts. # Do not trim this comment. -RHEL_RELEASE = 553.126.1 +RHEL_RELEASE = 553.129.1 # # ZSTREAM diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c index 0a03fffa4f..fa24c66878 100644 --- a/drivers/block/nbd.c +++ b/drivers/block/nbd.c @@ -2059,12 +2059,13 @@ again: } set_bit(NBD_RT_HAS_BACKEND_FILE, &config->runtime_flags); out: - mutex_unlock(&nbd->config_lock); if (!ret) { set_bit(NBD_RT_HAS_CONFIG_REF, &config->runtime_flags); refcount_inc(&nbd->config_refs); nbd_connect_reply(info, nbd->index); } + mutex_unlock(&nbd->config_lock); + nbd_config_put(nbd); if (put_dev) nbd_put(nbd); diff --git a/drivers/net/geneve.c b/drivers/net/geneve.c index dec064f563..7e85fd699b 100644 --- a/drivers/net/geneve.c +++ b/drivers/net/geneve.c @@ -1938,21 +1938,9 @@ static void geneve_destroy_tunnels(struct net *net, struct list_head *head) { struct geneve_net *gn = net_generic(net, geneve_net_id); struct geneve_dev *geneve, *next; - struct net_device *dev, *aux; - /* gather any geneve devices that were moved into this ns */ - for_each_netdev_safe(net, dev, aux) - if (dev->rtnl_link_ops == &geneve_link_ops) - unregister_netdevice_queue(dev, head); - - /* now gather any other geneve devices that were created in this ns */ - list_for_each_entry_safe(geneve, next, &gn->geneve_list, next) { - /* If geneve->dev is in the same netns, it was already added - * to the list by the previous loop. - */ - if (!net_eq(dev_net(geneve->dev), net)) - unregister_netdevice_queue(geneve->dev, head); - } + list_for_each_entry_safe(geneve, next, &gn->geneve_list, next) + geneve_dellink(geneve->dev, head); } static void __net_exit geneve_exit_batch_net(struct list_head *net_list) diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c index 9b86988d65..3d90b4d36f 100644 --- a/fs/cifs/smb2ops.c +++ b/fs/cifs/smb2ops.c @@ -3134,7 +3134,49 @@ parse_reparse_point(struct reparse_data_buffer *buf, } #define SMB2_SYMLINK_STRUCT_SIZE \ - (sizeof(struct smb2_err_rsp) - 1 + sizeof(struct smb2_symlink_err_rsp)) + (sizeof(struct smb2_err_rsp) + sizeof(struct smb2_symlink_err_rsp)) + +static struct smb2_symlink_err_rsp *symlink_data(const struct kvec *iov) +{ + struct smb2_err_rsp *err = iov->iov_base; + struct smb2_symlink_err_rsp *sym = ERR_PTR(-EINVAL); + u8 *end = (u8 *)err + iov->iov_len; + u32 len; + + if (err->ErrorContextCount) { + struct smb2_error_context_rsp *p; + + len = (u32)err->ErrorContextCount * (offsetof(struct smb2_error_context_rsp, + ErrorContextData) + + sizeof(struct smb2_symlink_err_rsp)); + if (le32_to_cpu(err->ByteCount) < len || iov->iov_len < len + sizeof(*err) + 1) + return ERR_PTR(-EINVAL); + + p = (struct smb2_error_context_rsp *)err->ErrorData; + while ((u8 *)p + sizeof(*p) <= end) { + if (le32_to_cpu(p->ErrorId) == SMB2_ERROR_ID_DEFAULT) { + sym = (struct smb2_symlink_err_rsp *)p->ErrorContextData; + break; + } + cifs_dbg(FYI, "%s: skipping unhandled error context: 0x%x\n", + __func__, le32_to_cpu(p->ErrorId)); + + len = ALIGN(le32_to_cpu(p->ErrorDataLength), 8); + p = (struct smb2_error_context_rsp *)(p->ErrorContextData + len); + } + } else if (le32_to_cpu(err->ByteCount) >= sizeof(*sym) && + iov->iov_len >= SMB2_SYMLINK_STRUCT_SIZE) { + sym = (struct smb2_symlink_err_rsp *)err->ErrorData; + } + + if (!IS_ERR(sym) && + ((u8 *)sym + sizeof(*sym) > end || + le32_to_cpu(sym->SymLinkErrorTag) != SYMLINK_ERROR_TAG || + le32_to_cpu(sym->ReparseTag) != IO_REPARSE_TAG_SYMLINK)) + sym = ERR_PTR(-EINVAL); + + return sym; +} static int smb2_query_symlink(const unsigned int xid, struct cifs_tcon *tcon, @@ -3147,7 +3189,6 @@ smb2_query_symlink(const unsigned int xid, struct cifs_tcon *tcon, struct cifs_open_parms oparms; struct cifs_fid fid; struct kvec err_iov = {NULL, 0}; - struct smb2_err_rsp *err_buf = NULL; struct smb2_symlink_err_rsp *symlink; struct TCP_Server_Info *server = cifs_pick_channel(tcon->ses); unsigned int sub_len; @@ -3165,6 +3206,7 @@ smb2_query_symlink(const unsigned int xid, struct cifs_tcon *tcon, struct smb2_ioctl_rsp *ioctl_rsp; struct reparse_data_buffer *reparse_buf; int create_options = is_reparse_point ? OPEN_REPARSE_POINT : 0; + size_t len; u32 plen; cifs_dbg(FYI, "%s: path: %s\n", __func__, full_path); @@ -3270,35 +3312,38 @@ smb2_query_symlink(const unsigned int xid, struct cifs_tcon *tcon, goto querty_exit; } - err_buf = err_iov.iov_base; - if (le32_to_cpu(err_buf->ByteCount) < sizeof(struct smb2_symlink_err_rsp) || - err_iov.iov_len < SMB2_SYMLINK_STRUCT_SIZE) { - rc = -EINVAL; - goto querty_exit; - } - - symlink = (struct smb2_symlink_err_rsp *)err_buf->ErrorData; - if (le32_to_cpu(symlink->SymLinkErrorTag) != SYMLINK_ERROR_TAG || - le32_to_cpu(symlink->ReparseTag) != IO_REPARSE_TAG_SYMLINK) { - rc = -EINVAL; - goto querty_exit; - } - /* open must fail on symlink - reset rc */ rc = 0; + symlink = symlink_data(&err_iov); + if (IS_ERR(symlink)) { + rc = PTR_ERR(symlink); + goto querty_exit; + } + sub_len = le16_to_cpu(symlink->SubstituteNameLength); sub_offset = le16_to_cpu(symlink->SubstituteNameOffset); print_len = le16_to_cpu(symlink->PrintNameLength); print_offset = le16_to_cpu(symlink->PrintNameOffset); - if (err_iov.iov_len < SMB2_SYMLINK_STRUCT_SIZE + sub_offset + sub_len) { + if ((char *)symlink->PathBuffer + sub_offset + sub_len > + (char *)err_iov.iov_base + err_iov.iov_len || + (char *)symlink->PathBuffer + print_offset + print_len > + (char *)err_iov.iov_base + err_iov.iov_len) { + cifs_dbg(VFS, "srv returned malformed symlink buffer\n"); rc = -EINVAL; goto querty_exit; } - if (err_iov.iov_len < - SMB2_SYMLINK_STRUCT_SIZE + print_offset + print_len) { - rc = -EINVAL; + if (!sub_len || (sub_len % 2)) { + cifs_dbg(VFS, "srv returned malformed symlink buffer\n"); + rc = -EIO; + goto querty_exit; + } + len = UniStrnlen((wchar_t *)((char *)symlink->PathBuffer + sub_offset), + sub_len / 2); + if (len != sub_len / 2) { + cifs_dbg(VFS, "srv returned null byte in native symlink target location\n"); + rc = -EIO; goto querty_exit; } diff --git a/fs/cifs/smb2pdu.h b/fs/cifs/smb2pdu.h index 5cc341d08e..c1a0219fef 100644 --- a/fs/cifs/smb2pdu.h +++ b/fs/cifs/smb2pdu.h @@ -57,7 +57,8 @@ struct smb2_rdma_encryption_transform { struct smb2_err_rsp { struct smb2_hdr hdr; __le16 StructureSize; - __le16 Reserved; /* MBZ */ + __u8 ErrorContextCount; + __u8 Reserved; __le32 ByteCount; /* even if zero, at least one byte follows */ __u8 ErrorData[]; /* variable length */ } __packed; @@ -82,7 +83,7 @@ struct smb2_symlink_err_rsp { struct smb2_error_context_rsp { __le32 ErrorDataLength; __le32 ErrorId; - __u8 ErrorContextData; /* ErrorDataLength long array */ + __u8 ErrorContextData[]; /* ErrorDataLength long array */ } __packed; /* ErrorId values */ diff --git a/net/ceph/messenger_v2.c b/net/ceph/messenger_v2.c index 7557ac2f1a..5c32ba7423 100644 --- a/net/ceph/messenger_v2.c +++ b/net/ceph/messenger_v2.c @@ -2191,7 +2191,9 @@ static int process_auth_done(struct ceph_connection *con, void *p, void *end) ceph_decode_64_safe(&p, end, global_id, bad); ceph_decode_32_safe(&p, end, con->v2.con_mode, bad); + ceph_decode_32_safe(&p, end, payload_len, bad); + ceph_decode_need(&p, end, payload_len, bad); dout("%s con %p global_id %llu con_mode %d payload_len %d\n", __func__, con, global_id, con->v2.con_mode, payload_len); diff --git a/net/ceph/osdmap.c b/net/ceph/osdmap.c index ce4a4c23fc..ddaf7b4c75 100644 --- a/net/ceph/osdmap.c +++ b/net/ceph/osdmap.c @@ -1959,11 +1959,13 @@ struct ceph_osdmap *osdmap_apply_incremental(void **p, void *end, bool msgr2, sizeof(u64) + sizeof(u32), e_inval); ceph_decode_copy(p, &fsid, sizeof(fsid)); epoch = ceph_decode_32(p); - BUG_ON(epoch != map->epoch+1); ceph_decode_copy(p, &modified, sizeof(modified)); new_pool_max = ceph_decode_64(p); new_flags = ceph_decode_32(p); + if (epoch != map->epoch + 1) + goto e_inval; + /* full map? */ ceph_decode_32_safe(p, end, len, e_inval); if (len > 0) { diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c index f6ea696092..94113c425d 100644 --- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c @@ -7071,6 +7071,7 @@ err5: kfree_rcu(hook, rcu); } err4: + synchronize_rcu(); flowtable->data.type->free(&flowtable->data); err3: module_put(type->owner); diff --git a/net/smc/af_smc.c b/net/smc/af_smc.c index 226d4ad179..64c40a93a9 100644 --- a/net/smc/af_smc.c +++ b/net/smc/af_smc.c @@ -3270,6 +3270,17 @@ static int __smc_create(struct net *net, struct socket *sock, int protocol, sk_common_release(sk); goto out; } + + /* smc_clcsock_release() does not wait smc->clcsock->sk's + * destruction; its sk_state might not be TCP_CLOSE after + * smc->sk is close()d, and TCP timers can be fired later, + * which need net ref. + */ + sk = smc->clcsock->sk; + sk->sk_net_refcnt = 1; + get_net(net); + sock_prot_inuse_add(net, sk->sk_prot, 1); + } else { smc->clcsock = clcsock; }