Import of kernel-6.12.0-211.28.1.el10_2

This commit is contained in:
almalinux-bot-kernel 2026-06-28 05:36:33 +00:00
parent f190b9663a
commit c259bc25aa
23 changed files with 143 additions and 121 deletions

View File

@ -597,8 +597,10 @@ static void vgic_its_invalidate_cache(struct vgic_its *its)
unsigned long idx;
xa_for_each(&its->translation_cache, idx, irq) {
xa_erase(&its->translation_cache, idx);
vgic_put_irq(kvm, irq);
/* Only the context that erases the entry drops its cache ref. */
irq = xa_erase(&its->translation_cache, idx);
if (irq)
vgic_put_irq(kvm, irq);
}
}

View File

@ -95,7 +95,6 @@ static struct workqueue_struct *iwcm_wq;
struct iwcm_work {
struct work_struct work;
struct iwcm_id_private *cm_id;
struct list_head list;
struct iw_cm_event event;
struct list_head free_list;
};
@ -178,7 +177,6 @@ static int alloc_work_entries(struct iwcm_id_private *cm_id_priv, int count)
return -ENOMEM;
}
work->cm_id = cm_id_priv;
INIT_LIST_HEAD(&work->list);
put_work(work);
}
return 0;
@ -213,7 +211,6 @@ static void free_cm_id(struct iwcm_id_private *cm_id_priv)
static bool iwcm_deref_id(struct iwcm_id_private *cm_id_priv)
{
if (refcount_dec_and_test(&cm_id_priv->refcount)) {
BUG_ON(!list_empty(&cm_id_priv->work_list));
free_cm_id(cm_id_priv);
return true;
}
@ -260,7 +257,6 @@ struct iw_cm_id *iw_create_cm_id(struct ib_device *device,
refcount_set(&cm_id_priv->refcount, 1);
init_waitqueue_head(&cm_id_priv->connect_wait);
init_completion(&cm_id_priv->destroy_comp);
INIT_LIST_HEAD(&cm_id_priv->work_list);
INIT_LIST_HEAD(&cm_id_priv->work_free_list);
return &cm_id_priv->id;
@ -1007,13 +1003,13 @@ static int process_event(struct iwcm_id_private *cm_id_priv,
}
/*
* Process events on the work_list for the cm_id. If the callback
* function requests that the cm_id be deleted, a flag is set in the
* cm_id flags to indicate that when the last reference is
* removed, the cm_id is to be destroyed. This is necessary to
* distinguish between an object that will be destroyed by the app
* thread asleep on the destroy_comp list vs. an object destroyed
* here synchronously when the last reference is removed.
* Process events for the cm_id. If the callback function requests
* that the cm_id be deleted, a flag is set in the cm_id flags to
* indicate that when the last reference is removed, the cm_id is
* to be destroyed. This is necessary to distinguish between an
* object that will be destroyed by the app thread asleep on the
* destroy_comp list vs. an object destroyed here synchronously
* when the last reference is removed.
*/
static void cm_work_handler(struct work_struct *_work)
{
@ -1024,35 +1020,26 @@ static void cm_work_handler(struct work_struct *_work)
int ret = 0;
spin_lock_irqsave(&cm_id_priv->lock, flags);
while (!list_empty(&cm_id_priv->work_list)) {
work = list_first_entry(&cm_id_priv->work_list,
struct iwcm_work, list);
list_del_init(&work->list);
levent = work->event;
put_work(work);
spin_unlock_irqrestore(&cm_id_priv->lock, flags);
if (!test_bit(IWCM_F_DROP_EVENTS, &cm_id_priv->flags)) {
ret = process_event(cm_id_priv, &levent);
if (ret) {
destroy_cm_id(&cm_id_priv->id);
WARN_ON_ONCE(iwcm_deref_id(cm_id_priv));
}
} else
pr_debug("dropping event %d\n", levent.event);
if (iwcm_deref_id(cm_id_priv))
return;
spin_lock_irqsave(&cm_id_priv->lock, flags);
}
levent = work->event;
put_work(work);
spin_unlock_irqrestore(&cm_id_priv->lock, flags);
if (!test_bit(IWCM_F_DROP_EVENTS, &cm_id_priv->flags)) {
ret = process_event(cm_id_priv, &levent);
if (ret) {
destroy_cm_id(&cm_id_priv->id);
WARN_ON_ONCE(iwcm_deref_id(cm_id_priv));
}
} else
pr_debug("dropping event %d\n", levent.event);
if (iwcm_deref_id(cm_id_priv))
return;
}
/*
* This function is called on interrupt context. Schedule events on
* the iwcm_wq thread to allow callback functions to downcall into
* the CM and/or block. Events are queued to a per-CM_ID
* work_list. If this is the first event on the work_list, the work
* element is also queued on the iwcm_wq thread.
* the CM and/or block.
*
* Each event holds a reference on the cm_id. Until the last posted
* event has been delivered and processed, the cm_id cannot be
@ -1094,7 +1081,6 @@ static int cm_event_handler(struct iw_cm_id *cm_id,
}
refcount_inc(&cm_id_priv->refcount);
list_add_tail(&work->list, &cm_id_priv->work_list);
queue_work(iwcm_wq, &work->work);
out:
spin_unlock_irqrestore(&cm_id_priv->lock, flags);

View File

@ -50,7 +50,6 @@ struct iwcm_id_private {
struct ib_qp *qp;
struct completion destroy_comp;
wait_queue_head_t connect_wait;
struct list_head work_list;
spinlock_t lock;
refcount_t refcount;
struct list_head work_free_list;

View File

@ -140,8 +140,9 @@ int mana_ib_install_cq_cb(struct mana_ib_dev *mdev, struct mana_ib_cq *cq)
if (cq->queue.id >= gc->max_num_cqs)
return -EINVAL;
/* Create CQ table entry */
WARN_ON(gc->cq_table[cq->queue.id]);
/* Create CQ table entry, sharing a CQ between WQs is not supported */
if (gc->cq_table[cq->queue.id])
return -EINVAL;
if (cq->queue.kmem)
gdma_cq = cq->queue.kmem;
else

View File

@ -21,6 +21,9 @@ static int mana_ib_cfg_vport_steering(struct mana_ib_dev *dev,
gc = mdev_to_gc(dev);
if (rx_hash_key_len > sizeof(req->hashkey))
return -EINVAL;
req_buf_size = struct_size(req, indir_tab, MANA_INDIRECT_TABLE_DEF_SIZE);
req = kzalloc(req_buf_size, GFP_KERNEL);
if (!req)

View File

@ -390,6 +390,19 @@ static void nvmet_tcp_fatal_error(struct nvmet_tcp_queue *queue)
static void nvmet_tcp_socket_error(struct nvmet_tcp_queue *queue, int status)
{
/*
* Keep rcv_state at RECV_ERR even for the internal -ESHUTDOWN path.
* nvmet_tcp_handle_icreq() can return -ESHUTDOWN after the ICReq has
* already been consumed and queue teardown has started.
*
* If nvmet_tcp_data_ready() or nvmet_tcp_write_space() queues
* nvmet_tcp_io_work() again before nvmet_tcp_release_queue_work()
* cancels it, the queue must not keep that old receive state.
* Otherwise the next nvmet_tcp_io_work() run can reach
* nvmet_tcp_done_recv_pdu() and try to handle the same ICReq again.
*
* That is why queue->rcv_state needs to be updated before we return.
*/
queue->rcv_state = NVMET_TCP_RECV_ERR;
if (status == -EPIPE || status == -ECONNRESET)
kernel_sock_shutdown(queue->sock, SHUT_RDWR);
@ -906,11 +919,24 @@ static int nvmet_tcp_handle_icreq(struct nvmet_tcp_queue *queue)
iov.iov_len = sizeof(*icresp);
ret = kernel_sendmsg(queue->sock, &msg, &iov, 1, iov.iov_len);
if (ret < 0) {
spin_lock_bh(&queue->state_lock);
if (queue->state == NVMET_TCP_Q_DISCONNECTING) {
spin_unlock_bh(&queue->state_lock);
return -ESHUTDOWN;
}
queue->state = NVMET_TCP_Q_FAILED;
spin_unlock_bh(&queue->state_lock);
return ret; /* queue removal will cleanup */
}
spin_lock_bh(&queue->state_lock);
if (queue->state == NVMET_TCP_Q_DISCONNECTING) {
spin_unlock_bh(&queue->state_lock);
/* Tell nvmet_tcp_socket_error() teardown is in progress. */
return -ESHUTDOWN;
}
queue->state = NVMET_TCP_Q_LIVE;
spin_unlock_bh(&queue->state_lock);
nvmet_prepare_receive_pdu(queue);
return 0;
}

View File

@ -2751,7 +2751,6 @@ qla24xx_els_dcmd_iocb(scsi_qla_host_t *vha, int els_opcode,
if (!elsio->u.els_logo.els_logo_pyld) {
/* ref: INIT */
kref_put(&sp->cmd_kref, qla2x00_sp_release);
qla2x00_free_fcport(fcport);
return QLA_FUNCTION_FAILED;
}
@ -2776,7 +2775,6 @@ qla24xx_els_dcmd_iocb(scsi_qla_host_t *vha, int els_opcode,
if (rval != QLA_SUCCESS) {
/* ref: INIT */
kref_put(&sp->cmd_kref, qla2x00_sp_release);
qla2x00_free_fcport(fcport);
return QLA_FUNCTION_FAILED;
}

View File

@ -42,7 +42,9 @@ struct inet_connection_sock_af_ops {
struct request_sock *req,
struct dst_entry *dst,
struct request_sock *req_unhash,
bool *own_req);
bool *own_req,
void (*opt_child_init)(struct sock *newsk,
const struct sock *sk));
u16 net_header_len;
u16 sockaddr_len;
int (*setsockopt)(struct sock *sk, int level, int optname,

View File

@ -465,7 +465,9 @@ struct sock *tcp_v4_syn_recv_sock(const struct sock *sk, struct sk_buff *skb,
struct request_sock *req,
struct dst_entry *dst,
struct request_sock *req_unhash,
bool *own_req);
bool *own_req,
void (*opt_child_init)(struct sock *newsk,
const struct sock *sk));
int tcp_v4_do_rcv(struct sock *sk, struct sk_buff *skb);
int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len);
int tcp_connect(struct sock *sk);

View File

@ -1,2 +1,2 @@
sbat,1,SBAT Version,sbat,1,https://github.com/rhboot/shim/blob/main/SBAT.md
kernel.almalinux,1,AlmaLinux,kernel-core,6.12.0-211.26.1.el10.x86_64,mailto:security@almalinux.org
kernel.almalinux,1,AlmaLinux,kernel-core,6.12.0-211.28.1.el10.x86_64,mailto:security@almalinux.org

View File

@ -202,7 +202,7 @@ struct sock *tcp_get_cookie_sock(struct sock *sk, struct sk_buff *skb,
bool own_req;
child = icsk->icsk_af_ops->syn_recv_sock(sk, skb, req, dst,
NULL, &own_req);
NULL, &own_req, NULL);
if (child) {
refcount_set(&req->rsk_refcnt, 1);
sock_rps_save_rxhash(child, skb);

View File

@ -247,7 +247,7 @@ static struct sock *tcp_fastopen_create_child(struct sock *sk,
bool own_req;
child = inet_csk(sk)->icsk_af_ops->syn_recv_sock(sk, skb, req, NULL,
NULL, &own_req);
NULL, &own_req, NULL);
if (!child)
return NULL;

View File

@ -1739,7 +1739,9 @@ struct sock *tcp_v4_syn_recv_sock(const struct sock *sk, struct sk_buff *skb,
struct request_sock *req,
struct dst_entry *dst,
struct request_sock *req_unhash,
bool *own_req)
bool *own_req,
void (*opt_child_init)(struct sock *newsk,
const struct sock *sk))
{
struct inet_request_sock *ireq;
bool found_dup_sk = false;
@ -1795,6 +1797,10 @@ struct sock *tcp_v4_syn_recv_sock(const struct sock *sk, struct sk_buff *skb,
}
sk_setup_caps(newsk, dst);
#if IS_ENABLED(CONFIG_IPV6)
if (opt_child_init)
opt_child_init(newsk, sk);
#endif
tcp_ca_openreq_child(newsk, dst);
tcp_sync_mss(newsk, dst_mtu(dst));

View File

@ -862,7 +862,7 @@ struct sock *tcp_check_req(struct sock *sk, struct sk_buff *skb,
* socket is created, wait for troubles.
*/
child = inet_csk(sk)->icsk_af_ops->syn_recv_sock(sk, skb, req, NULL,
req, &own_req);
req, &own_req, NULL);
if (!child)
goto listen_overflow;

View File

@ -681,6 +681,9 @@ int ip6_err_gen_icmpv6_unreach(struct sk_buff *skb, int nhs, int type,
if (!skb2)
return 1;
/* Remove debris left by IPv4 stack. */
memset(IP6CB(skb2), 0, sizeof(*IP6CB(skb2)));
skb_dst_drop(skb2);
skb_pull(skb2, nhs);
skb_reset_network_header(skb2);

View File

@ -1343,11 +1343,48 @@ static void tcp_v6_restore_cb(struct sk_buff *skb)
sizeof(struct inet6_skb_parm));
}
/* Called from tcp_v4_syn_recv_sock() for v6_mapped children. */
static void tcp_v6_mapped_child_init(struct sock *newsk, const struct sock *sk)
{
struct inet_sock *newinet = inet_sk(newsk);
struct ipv6_pinfo *newnp;
newinet->pinet6 = newnp = tcp_inet6_sk(newsk);
memcpy(newnp, tcp_inet6_sk(sk), sizeof(struct ipv6_pinfo));
newnp->saddr = newsk->sk_v6_rcv_saddr;
inet_csk(newsk)->icsk_af_ops = &ipv6_mapped;
if (sk_is_mptcp(newsk))
mptcpv6_handle_mapped(newsk, true);
newsk->sk_backlog_rcv = tcp_v4_do_rcv;
#if defined(CONFIG_TCP_MD5SIG) || defined(CONFIG_TCP_AO)
tcp_sk(newsk)->af_specific = &tcp_sock_ipv6_mapped_specific;
#endif
newnp->ipv6_mc_list = NULL;
newnp->ipv6_ac_list = NULL;
newnp->ipv6_fl_list = NULL;
newnp->pktoptions = NULL;
newnp->opt = NULL;
/* tcp_v4_syn_recv_sock() has initialized newinet->mc_{index,ttl} */
newnp->mcast_oif = newinet->mc_index;
newnp->mcast_hops = newinet->mc_ttl;
newnp->rcv_flowinfo = 0;
if (inet6_test_bit(REPFLOW, sk))
newnp->flow_label = 0;
}
static struct sock *tcp_v6_syn_recv_sock(const struct sock *sk, struct sk_buff *skb,
struct request_sock *req,
struct dst_entry *dst,
struct request_sock *req_unhash,
bool *own_req)
bool *own_req,
void (*opt_child_init)(struct sock *newsk,
const struct sock *sk))
{
struct inet_request_sock *ireq;
struct ipv6_pinfo *newnp;
@ -1363,60 +1400,10 @@ static struct sock *tcp_v6_syn_recv_sock(const struct sock *sk, struct sk_buff *
#endif
struct flowi6 fl6;
if (skb->protocol == htons(ETH_P_IP)) {
/*
* v6 mapped
*/
newsk = tcp_v4_syn_recv_sock(sk, skb, req, dst,
req_unhash, own_req);
if (!newsk)
return NULL;
inet_sk(newsk)->pinet6 = tcp_inet6_sk(newsk);
newnp = tcp_inet6_sk(newsk);
newtp = tcp_sk(newsk);
memcpy(newnp, np, sizeof(struct ipv6_pinfo));
newnp->saddr = newsk->sk_v6_rcv_saddr;
inet_csk(newsk)->icsk_af_ops = &ipv6_mapped;
if (sk_is_mptcp(newsk))
mptcpv6_handle_mapped(newsk, true);
newsk->sk_backlog_rcv = tcp_v4_do_rcv;
#if defined(CONFIG_TCP_MD5SIG) || defined(CONFIG_TCP_AO)
newtp->af_specific = &tcp_sock_ipv6_mapped_specific;
#endif
newnp->ipv6_mc_list = NULL;
newnp->ipv6_ac_list = NULL;
newnp->ipv6_fl_list = NULL;
newnp->pktoptions = NULL;
newnp->opt = NULL;
newnp->mcast_oif = inet_iif(skb);
newnp->mcast_hops = ip_hdr(skb)->ttl;
newnp->rcv_flowinfo = 0;
if (inet6_test_bit(REPFLOW, sk))
newnp->flow_label = 0;
/*
* No need to charge this sock to the relevant IPv6 refcnt debug socks count
* here, tcp_create_openreq_child now does this for us, see the comment in
* that function for the gory details. -acme
*/
/* It is tricky place. Until this moment IPv4 tcp
worked with IPv6 icsk.icsk_af_ops.
Sync it now.
*/
tcp_sync_mss(newsk, inet_csk(newsk)->icsk_pmtu_cookie);
return newsk;
}
if (skb->protocol == htons(ETH_P_IP))
return tcp_v4_syn_recv_sock(sk, skb, req, dst,
req_unhash, own_req,
tcp_v6_mapped_child_init);
ireq = inet_rsk(req);
if (sk_acceptq_is_full(sk))

View File

@ -809,7 +809,9 @@ static struct sock *subflow_syn_recv_sock(const struct sock *sk,
struct request_sock *req,
struct dst_entry *dst,
struct request_sock *req_unhash,
bool *own_req)
bool *own_req,
void (*opt_child_init)(struct sock *newsk,
const struct sock *sk))
{
struct mptcp_subflow_context *listener = mptcp_subflow_ctx(sk);
struct mptcp_subflow_request_sock *subflow_req;
@ -856,7 +858,7 @@ static struct sock *subflow_syn_recv_sock(const struct sock *sk,
create_child:
child = listener->icsk_af_ops->syn_recv_sock(sk, skb, req, dst,
req_unhash, own_req);
req_unhash, own_req, opt_child_init);
if (child && *own_req) {
struct mptcp_subflow_context *ctx = mptcp_subflow_ctx(child);

View File

@ -1164,7 +1164,8 @@ static int rxgk_verify_authenticator(struct rxrpc_connection *conn,
}
p = auth;
ret = rxgk_do_verify_authenticator(conn, krb5, skb, p, p + auth_len);
ret = rxgk_do_verify_authenticator(conn, krb5, skb, p,
p + auth_len / sizeof(*p));
error:
kfree(auth);
return ret;

View File

@ -125,7 +125,9 @@ static struct sock *smc_tcp_syn_recv_sock(const struct sock *sk,
struct request_sock *req,
struct dst_entry *dst,
struct request_sock *req_unhash,
bool *own_req)
bool *own_req,
void (*opt_child_init)(struct sock *newsk,
const struct sock *sk))
{
struct smc_sock *smc;
struct sock *child;
@ -143,7 +145,7 @@ static struct sock *smc_tcp_syn_recv_sock(const struct sock *sk,
/* passthrough to original syn recv sock fct */
child = smc->ori_af_ops->syn_recv_sock(sk, skb, req, dst, req_unhash,
own_req);
own_req, opt_child_init);
/* child must not inherit smc or its ops */
if (child) {
rcu_assign_sk_user_data(child, NULL);

View File

@ -3808,7 +3808,7 @@ static int default_noexec __ro_after_init;
static int __file_map_prot_check(const struct cred *cred,
const struct file *file, unsigned long prot,
bool shared, bool bf_user_file)
bool shared, bool mounter, bool bf_user_file)
{
struct inode *inode = NULL;
bool prot_exec = prot & PROT_EXEC;
@ -3822,7 +3822,7 @@ static int __file_map_prot_check(const struct cred *cred,
}
if (default_noexec && prot_exec &&
(!file || IS_PRIVATE(inode) || (!shared && prot_write))) {
(!file || IS_PRIVATE(inode) || (!shared && prot_write)) && !mounter) {
int rc;
u32 sid = cred_sid(cred);
@ -3852,9 +3852,9 @@ static int __file_map_prot_check(const struct cred *cred,
static inline int file_map_prot_check(const struct cred *cred,
const struct file *file,
unsigned long prot, bool shared)
unsigned long prot, bool shared, bool mounter)
{
return __file_map_prot_check(cred, file, prot, shared, false);
return __file_map_prot_check(cred, file, prot, shared, mounter, false);
}
static int selinux_mmap_addr(unsigned long addr)
@ -3871,7 +3871,7 @@ static int selinux_mmap_addr(unsigned long addr)
}
static int selinux_mmap_file_common(const struct cred *cred, struct file *file,
unsigned long prot, bool shared)
unsigned long prot, bool shared, bool mounter)
{
if (file) {
int rc;
@ -3884,7 +3884,7 @@ static int selinux_mmap_file_common(const struct cred *cred, struct file *file,
return rc;
}
return file_map_prot_check(cred, file, prot, shared);
return file_map_prot_check(cred, file, prot, shared, mounter);
}
static int selinux_mmap_file(struct file *file,
@ -3892,7 +3892,8 @@ static int selinux_mmap_file(struct file *file,
unsigned long prot, unsigned long flags)
{
return selinux_mmap_file_common(current_cred(), file, prot,
(flags & MAP_TYPE) == MAP_SHARED);
(flags & MAP_TYPE) == MAP_SHARED,
false);
}
/**
@ -3925,7 +3926,8 @@ static int selinux_mmap_backing_file(struct vm_area_struct *vma,
prot |= PROT_EXEC;
return selinux_mmap_file_common(backing_file->f_cred, backing_file,
prot, vma->vm_flags & VM_SHARED);
prot, vma->vm_flags & VM_SHARED,
true);
}
static int selinux_file_mprotect(struct vm_area_struct *vma,
@ -3986,11 +3988,11 @@ static int selinux_file_mprotect(struct vm_area_struct *vma,
}
}
rc = __file_map_prot_check(cred, file, prot, shared, backing_file);
rc = __file_map_prot_check(cred, file, prot, shared, false, backing_file);
if (rc)
return rc;
if (backing_file) {
rc = file_map_prot_check(file->f_cred, file, prot, shared);
rc = file_map_prot_check(file->f_cred, file, prot, shared, true);
if (rc)
return rc;
}

View File

@ -1,2 +1,2 @@
sbat,1,SBAT Version,sbat,1,https://github.com/rhboot/shim/blob/main/SBAT.md
kernel-uki-virt-addons.almalinux,1,AlmaLinux,kernel-uki-virt-addons,6.12.0-211.26.1.el10.x86_64,mailto:security@almalinux.org
kernel-uki-virt-addons.almalinux,1,AlmaLinux,kernel-uki-virt-addons,6.12.0-211.28.1.el10.x86_64,mailto:security@almalinux.org

View File

@ -1,2 +1,2 @@
sbat,1,SBAT Version,sbat,1,https://github.com/rhboot/shim/blob/main/SBAT.md
kernel-uki-virt.almalinux,1,AlmaLinux,kernel-uki-virt,6.12.0-211.26.1.el10.x86_64,mailto:security@almalinux.org
kernel-uki-virt.almalinux,1,AlmaLinux,kernel-uki-virt,6.12.0-211.28.1.el10.x86_64,mailto:security@almalinux.org