Recreate RHEL 6.12.0-211.16.1 from CS10/upstream backports

Drop the 211.7.x security-ahead patches superseded by the RHEL 211.8.1..211.16.1
backports (1100-1104), add those backports (1106-1161) from centos-stream-10 and
upstream linux-6.12.y. Keep the smb cifs.spnego ahead-fix (1105). Bump to 211.16.1.
This commit is contained in:
Andrew Lukoshko 2026-06-07 00:03:47 +00:00
parent b3c4cf07f6
commit b3393f484c
62 changed files with 4933 additions and 1311 deletions

View File

@ -1,952 +0,0 @@
From: AlmaLinux Backport <packager@almalinux.org>
Subject: [PATCH] CVE-2026-31431 ("Copy Fail"): crypto AEAD/algif fixes from linux-6.12.y
Combined backport addressing CVE-2026-31431 ("Copy Fail"), reported by
Taeyang Lee <0wn@theori.io>. Pulls one prerequisite (committed 2026-01-30
to linux-6.12.y) plus eight 2026-04-30 stable fixes:
161bdc90fce2 crypto: authencesn - reject too-short AAD (assoclen<8) to match ESP/ESN spec
41c3aa511e6e crypto: scatterwalk - Backport memcpy_sglist()
183137264401 crypto: algif_aead - use memcpy_sglist() instead of null skcipher
8b88d99341f1 crypto: algif_aead - Revert to operating out-of-place
46fdb39e8322 crypto: algif_aead - snapshot IV for async AEAD requests
7bc058a9b82b crypto: authenc - use memcpy_sglist() instead of null skcipher
89fe118b6470 crypto: authencesn - Do not place hiseq at end of dst for out-of-place decryption
129f12934401 crypto: authencesn - Fix src offset when decrypting in-place
c8369a6d62f5 crypto: af_alg - Fix page reassignment overflow in af_alg_pull_tsgl
161bdc90 is the prerequisite for 89fe118b6470 to apply.
Signed-off-by: Andrew Lukoshko <alukoshko@almalinux.org>
---
--- a/crypto/af_alg.c
+++ b/crypto/af_alg.c
@@ -635,15 +635,13 @@
/**
* af_alg_count_tsgl - Count number of TX SG entries
*
- * The counting starts from the beginning of the SGL to @bytes. If
- * an @offset is provided, the counting of the SG entries starts at the @offset.
+ * The counting starts from the beginning of the SGL to @bytes.
*
* @sk: socket of connection to user space
* @bytes: Count the number of SG entries holding given number of bytes.
- * @offset: Start the counting of SG entries from the given offset.
* Return: Number of TX SG entries found given the constraints
*/
-unsigned int af_alg_count_tsgl(struct sock *sk, size_t bytes, size_t offset)
+unsigned int af_alg_count_tsgl(struct sock *sk, size_t bytes)
{
const struct alg_sock *ask = alg_sk(sk);
const struct af_alg_ctx *ctx = ask->private;
@@ -658,25 +656,11 @@
const struct scatterlist *sg = sgl->sg;
for (i = 0; i < sgl->cur; i++) {
- size_t bytes_count;
-
- /* Skip offset */
- if (offset >= sg[i].length) {
- offset -= sg[i].length;
- bytes -= sg[i].length;
- continue;
- }
-
- bytes_count = sg[i].length - offset;
-
- offset = 0;
sgl_count++;
-
- /* If we have seen requested number of bytes, stop */
- if (bytes_count >= bytes)
+ if (sg[i].length >= bytes)
return sgl_count;
- bytes -= bytes_count;
+ bytes -= sg[i].length;
}
}
@@ -688,19 +672,14 @@
* af_alg_pull_tsgl - Release the specified buffers from TX SGL
*
* If @dst is non-null, reassign the pages to @dst. The caller must release
- * the pages. If @dst_offset is given only reassign the pages to @dst starting
- * at the @dst_offset (byte). The caller must ensure that @dst is large
- * enough (e.g. by using af_alg_count_tsgl with the same offset).
+ * the pages.
*
* @sk: socket of connection to user space
* @used: Number of bytes to pull from TX SGL
* @dst: If non-NULL, buffer is reassigned to dst SGL instead of releasing. The
* caller must release the buffers in dst.
- * @dst_offset: Reassign the TX SGL from given offset. All buffers before
- * reaching the offset is released.
*/
-void af_alg_pull_tsgl(struct sock *sk, size_t used, struct scatterlist *dst,
- size_t dst_offset)
+void af_alg_pull_tsgl(struct sock *sk, size_t used, struct scatterlist *dst)
{
struct alg_sock *ask = alg_sk(sk);
struct af_alg_ctx *ctx = ask->private;
@@ -724,19 +703,11 @@
* Assumption: caller created af_alg_count_tsgl(len)
* SG entries in dst.
*/
- if (dst) {
- if (dst_offset >= plen) {
- /* discard page before offset */
- dst_offset -= plen;
- } else {
- /* reassign page to dst after offset */
- get_page(page);
- sg_set_page(dst + j, page,
- plen - dst_offset,
- sg[i].offset + dst_offset);
- dst_offset = 0;
- j++;
- }
+ if (dst && plen) {
+ /* reassign page to dst */
+ get_page(page);
+ sg_set_page(dst + j, page, plen, sg[i].offset);
+ j++;
}
sg[i].length -= plen;
--- a/crypto/algif_aead.c
+++ b/crypto/algif_aead.c
@@ -26,8 +26,6 @@
#include <crypto/internal/aead.h>
#include <crypto/scatterwalk.h>
#include <crypto/if_alg.h>
-#include <crypto/skcipher.h>
-#include <crypto/null.h>
#include <linux/init.h>
#include <linux/list.h>
#include <linux/kernel.h>
@@ -36,19 +34,13 @@
#include <linux/net.h>
#include <net/sock.h>
-struct aead_tfm {
- struct crypto_aead *aead;
- struct crypto_sync_skcipher *null_tfm;
-};
-
static inline bool aead_sufficient_data(struct sock *sk)
{
struct alg_sock *ask = alg_sk(sk);
struct sock *psk = ask->parent;
struct alg_sock *pask = alg_sk(psk);
struct af_alg_ctx *ctx = ask->private;
- struct aead_tfm *aeadc = pask->private;
- struct crypto_aead *tfm = aeadc->aead;
+ struct crypto_aead *tfm = pask->private;
unsigned int as = crypto_aead_authsize(tfm);
/*
@@ -64,27 +56,12 @@
struct alg_sock *ask = alg_sk(sk);
struct sock *psk = ask->parent;
struct alg_sock *pask = alg_sk(psk);
- struct aead_tfm *aeadc = pask->private;
- struct crypto_aead *tfm = aeadc->aead;
+ struct crypto_aead *tfm = pask->private;
unsigned int ivsize = crypto_aead_ivsize(tfm);
return af_alg_sendmsg(sock, msg, size, ivsize);
}
-static int crypto_aead_copy_sgl(struct crypto_sync_skcipher *null_tfm,
- struct scatterlist *src,
- struct scatterlist *dst, unsigned int len)
-{
- SYNC_SKCIPHER_REQUEST_ON_STACK(skreq, null_tfm);
-
- skcipher_request_set_sync_tfm(skreq, null_tfm);
- skcipher_request_set_callback(skreq, CRYPTO_TFM_REQ_MAY_SLEEP,
- NULL, NULL);
- skcipher_request_set_crypt(skreq, src, dst, len, NULL);
-
- return crypto_skcipher_encrypt(skreq);
-}
-
static int _aead_recvmsg(struct socket *sock, struct msghdr *msg,
size_t ignored, int flags)
{
@@ -93,13 +70,12 @@
struct sock *psk = ask->parent;
struct alg_sock *pask = alg_sk(psk);
struct af_alg_ctx *ctx = ask->private;
- struct aead_tfm *aeadc = pask->private;
- struct crypto_aead *tfm = aeadc->aead;
- struct crypto_sync_skcipher *null_tfm = aeadc->null_tfm;
- unsigned int i, as = crypto_aead_authsize(tfm);
+ struct crypto_aead *tfm = pask->private;
+ unsigned int as = crypto_aead_authsize(tfm);
+ unsigned int ivsize = crypto_aead_ivsize(tfm);
struct af_alg_async_req *areq;
- struct af_alg_tsgl *tsgl, *tmp;
struct scatterlist *rsgl_src, *tsgl_src = NULL;
+ void *iv;
int err = 0;
size_t used = 0; /* [in] TX bufs to be en/decrypted */
size_t outlen = 0; /* [out] RX bufs produced by kernel */
@@ -151,10 +127,14 @@
/* Allocate cipher request for current operation. */
areq = af_alg_alloc_areq(sk, sizeof(struct af_alg_async_req) +
- crypto_aead_reqsize(tfm));
+ crypto_aead_reqsize(tfm) + ivsize);
if (IS_ERR(areq))
return PTR_ERR(areq);
+ iv = (u8 *)aead_request_ctx(&areq->cra_u.aead_req) +
+ crypto_aead_reqsize(tfm);
+ memcpy(iv, ctx->iv, ivsize);
+
/* convert iovecs of output buffers into RX SGL */
err = af_alg_get_rsgl(sk, msg, flags, areq, outlen, &usedpages);
if (err)
@@ -178,23 +158,24 @@
outlen -= less;
}
+ /*
+ * Create a per request TX SGL for this request which tracks the
+ * SG entries from the global TX SGL.
+ */
processed = used + ctx->aead_assoclen;
- list_for_each_entry_safe(tsgl, tmp, &ctx->tsgl_list, list) {
- for (i = 0; i < tsgl->cur; i++) {
- struct scatterlist *process_sg = tsgl->sg + i;
-
- if (!(process_sg->length) || !sg_page(process_sg))
- continue;
- tsgl_src = process_sg;
- break;
- }
- if (tsgl_src)
- break;
- }
- if (processed && !tsgl_src) {
- err = -EFAULT;
+ areq->tsgl_entries = af_alg_count_tsgl(sk, processed);
+ if (!areq->tsgl_entries)
+ areq->tsgl_entries = 1;
+ areq->tsgl = sock_kmalloc(sk, array_size(sizeof(*areq->tsgl),
+ areq->tsgl_entries),
+ GFP_KERNEL);
+ if (!areq->tsgl) {
+ err = -ENOMEM;
goto free;
}
+ sg_init_table(areq->tsgl, areq->tsgl_entries);
+ af_alg_pull_tsgl(sk, processed, areq->tsgl);
+ tsgl_src = areq->tsgl;
/*
* Copy of AAD from source to destination
@@ -203,84 +184,16 @@
* when user space uses an in-place cipher operation, the kernel
* will copy the data as it does not see whether such in-place operation
* is initiated.
- *
- * To ensure efficiency, the following implementation ensure that the
- * ciphers are invoked to perform a crypto operation in-place. This
- * is achieved by memory management specified as follows.
*/
/* Use the RX SGL as source (and destination) for crypto op. */
rsgl_src = areq->first_rsgl.sgl.sgt.sgl;
- if (ctx->enc) {
- /*
- * Encryption operation - The in-place cipher operation is
- * achieved by the following operation:
- *
- * TX SGL: AAD || PT
- * | |
- * | copy |
- * v v
- * RX SGL: AAD || PT || Tag
- */
- err = crypto_aead_copy_sgl(null_tfm, tsgl_src,
- areq->first_rsgl.sgl.sgt.sgl,
- processed);
- if (err)
- goto free;
- af_alg_pull_tsgl(sk, processed, NULL, 0);
- } else {
- /*
- * Decryption operation - To achieve an in-place cipher
- * operation, the following SGL structure is used:
- *
- * TX SGL: AAD || CT || Tag
- * | | ^
- * | copy | | Create SGL link.
- * v v |
- * RX SGL: AAD || CT ----+
- */
-
- /* Copy AAD || CT to RX SGL buffer for in-place operation. */
- err = crypto_aead_copy_sgl(null_tfm, tsgl_src,
- areq->first_rsgl.sgl.sgt.sgl,
- outlen);
- if (err)
- goto free;
-
- /* Create TX SGL for tag and chain it to RX SGL. */
- areq->tsgl_entries = af_alg_count_tsgl(sk, processed,
- processed - as);
- if (!areq->tsgl_entries)
- areq->tsgl_entries = 1;
- areq->tsgl = sock_kmalloc(sk, array_size(sizeof(*areq->tsgl),
- areq->tsgl_entries),
- GFP_KERNEL);
- if (!areq->tsgl) {
- err = -ENOMEM;
- goto free;
- }
- sg_init_table(areq->tsgl, areq->tsgl_entries);
-
- /* Release TX SGL, except for tag data and reassign tag data. */
- af_alg_pull_tsgl(sk, processed, areq->tsgl, processed - as);
-
- /* chain the areq TX SGL holding the tag with RX SGL */
- if (usedpages) {
- /* RX SGL present */
- struct af_alg_sgl *sgl_prev = &areq->last_rsgl->sgl;
- struct scatterlist *sg = sgl_prev->sgt.sgl;
-
- sg_unmark_end(sg + sgl_prev->sgt.nents - 1);
- sg_chain(sg, sgl_prev->sgt.nents + 1, areq->tsgl);
- } else
- /* no RX SGL present (e.g. authentication only) */
- rsgl_src = areq->tsgl;
- }
+ memcpy_sglist(rsgl_src, tsgl_src, ctx->aead_assoclen);
/* Initialize the crypto operation */
- aead_request_set_crypt(&areq->cra_u.aead_req, rsgl_src,
- areq->first_rsgl.sgl.sgt.sgl, used, ctx->iv);
+ aead_request_set_crypt(&areq->cra_u.aead_req, tsgl_src,
+ areq->first_rsgl.sgl.sgt.sgl, used, iv);
aead_request_set_ad(&areq->cra_u.aead_req, ctx->aead_assoclen);
aead_request_set_tfm(&areq->cra_u.aead_req, tfm);
@@ -379,7 +292,7 @@
int err = 0;
struct sock *psk;
struct alg_sock *pask;
- struct aead_tfm *tfm;
+ struct crypto_aead *tfm;
struct sock *sk = sock->sk;
struct alg_sock *ask = alg_sk(sk);
@@ -393,7 +306,7 @@
err = -ENOKEY;
lock_sock_nested(psk, SINGLE_DEPTH_NESTING);
- if (crypto_aead_get_flags(tfm->aead) & CRYPTO_TFM_NEED_KEY)
+ if (crypto_aead_get_flags(tfm) & CRYPTO_TFM_NEED_KEY)
goto unlock;
atomic_dec(&pask->nokey_refcnt);
@@ -454,54 +367,22 @@
static void *aead_bind(const char *name, u32 type, u32 mask)
{
- struct aead_tfm *tfm;
- struct crypto_aead *aead;
- struct crypto_sync_skcipher *null_tfm;
-
- tfm = kzalloc(sizeof(*tfm), GFP_KERNEL);
- if (!tfm)
- return ERR_PTR(-ENOMEM);
-
- aead = crypto_alloc_aead(name, type, mask);
- if (IS_ERR(aead)) {
- kfree(tfm);
- return ERR_CAST(aead);
- }
-
- null_tfm = crypto_get_default_null_skcipher();
- if (IS_ERR(null_tfm)) {
- crypto_free_aead(aead);
- kfree(tfm);
- return ERR_CAST(null_tfm);
- }
-
- tfm->aead = aead;
- tfm->null_tfm = null_tfm;
-
- return tfm;
+ return crypto_alloc_aead(name, type, mask);
}
static void aead_release(void *private)
{
- struct aead_tfm *tfm = private;
-
- crypto_free_aead(tfm->aead);
- crypto_put_default_null_skcipher();
- kfree(tfm);
+ crypto_free_aead(private);
}
static int aead_setauthsize(void *private, unsigned int authsize)
{
- struct aead_tfm *tfm = private;
-
- return crypto_aead_setauthsize(tfm->aead, authsize);
+ return crypto_aead_setauthsize(private, authsize);
}
static int aead_setkey(void *private, const u8 *key, unsigned int keylen)
{
- struct aead_tfm *tfm = private;
-
- return crypto_aead_setkey(tfm->aead, key, keylen);
+ return crypto_aead_setkey(private, key, keylen);
}
static void aead_sock_destruct(struct sock *sk)
@@ -510,11 +391,10 @@
struct af_alg_ctx *ctx = ask->private;
struct sock *psk = ask->parent;
struct alg_sock *pask = alg_sk(psk);
- struct aead_tfm *aeadc = pask->private;
- struct crypto_aead *tfm = aeadc->aead;
+ struct crypto_aead *tfm = pask->private;
unsigned int ivlen = crypto_aead_ivsize(tfm);
- af_alg_pull_tsgl(sk, ctx->used, NULL, 0);
+ af_alg_pull_tsgl(sk, ctx->used, NULL);
sock_kzfree_s(sk, ctx->iv, ivlen);
sock_kfree_s(sk, ctx, ctx->len);
af_alg_release_parent(sk);
@@ -524,10 +404,9 @@
{
struct af_alg_ctx *ctx;
struct alg_sock *ask = alg_sk(sk);
- struct aead_tfm *tfm = private;
- struct crypto_aead *aead = tfm->aead;
+ struct crypto_aead *tfm = private;
unsigned int len = sizeof(*ctx);
- unsigned int ivlen = crypto_aead_ivsize(aead);
+ unsigned int ivlen = crypto_aead_ivsize(tfm);
ctx = sock_kmalloc(sk, len, GFP_KERNEL);
if (!ctx)
@@ -554,9 +433,9 @@
static int aead_accept_parent(void *private, struct sock *sk)
{
- struct aead_tfm *tfm = private;
+ struct crypto_aead *tfm = private;
- if (crypto_aead_get_flags(tfm->aead) & CRYPTO_TFM_NEED_KEY)
+ if (crypto_aead_get_flags(tfm) & CRYPTO_TFM_NEED_KEY)
return -ENOKEY;
return aead_accept_parent_nokey(private, sk);
--- a/crypto/algif_skcipher.c
+++ b/crypto/algif_skcipher.c
@@ -138,7 +138,7 @@
* Create a per request TX SGL for this request which tracks the
* SG entries from the global TX SGL.
*/
- areq->tsgl_entries = af_alg_count_tsgl(sk, len, 0);
+ areq->tsgl_entries = af_alg_count_tsgl(sk, len);
if (!areq->tsgl_entries)
areq->tsgl_entries = 1;
areq->tsgl = sock_kmalloc(sk, array_size(sizeof(*areq->tsgl),
@@ -149,7 +149,7 @@
goto free;
}
sg_init_table(areq->tsgl, areq->tsgl_entries);
- af_alg_pull_tsgl(sk, len, areq->tsgl, 0);
+ af_alg_pull_tsgl(sk, len, areq->tsgl);
/* Initialize the crypto operation */
skcipher_request_set_tfm(&areq->cra_u.skcipher_req, tfm);
@@ -363,7 +363,7 @@
struct alg_sock *pask = alg_sk(psk);
struct crypto_skcipher *tfm = pask->private;
- af_alg_pull_tsgl(sk, ctx->used, NULL, 0);
+ af_alg_pull_tsgl(sk, ctx->used, NULL);
sock_kzfree_s(sk, ctx->iv, crypto_skcipher_ivsize(tfm));
if (ctx->state)
sock_kzfree_s(sk, ctx->state, crypto_skcipher_statesize(tfm));
--- a/crypto/authenc.c
+++ b/crypto/authenc.c
@@ -9,7 +9,6 @@
#include <crypto/internal/hash.h>
#include <crypto/internal/skcipher.h>
#include <crypto/authenc.h>
-#include <crypto/null.h>
#include <crypto/scatterwalk.h>
#include <linux/err.h>
#include <linux/init.h>
@@ -28,7 +27,6 @@
struct crypto_authenc_ctx {
struct crypto_ahash *auth;
struct crypto_skcipher *enc;
- struct crypto_sync_skcipher *null;
};
struct authenc_request_ctx {
@@ -170,21 +168,6 @@
authenc_request_complete(areq, err);
}
-static int crypto_authenc_copy_assoc(struct aead_request *req)
-{
- struct crypto_aead *authenc = crypto_aead_reqtfm(req);
- struct crypto_authenc_ctx *ctx = crypto_aead_ctx(authenc);
- SYNC_SKCIPHER_REQUEST_ON_STACK(skreq, ctx->null);
-
- skcipher_request_set_sync_tfm(skreq, ctx->null);
- skcipher_request_set_callback(skreq, aead_request_flags(req),
- NULL, NULL);
- skcipher_request_set_crypt(skreq, req->src, req->dst, req->assoclen,
- NULL);
-
- return crypto_skcipher_encrypt(skreq);
-}
-
static int crypto_authenc_encrypt(struct aead_request *req)
{
struct crypto_aead *authenc = crypto_aead_reqtfm(req);
@@ -203,10 +186,7 @@
dst = src;
if (req->src != req->dst) {
- err = crypto_authenc_copy_assoc(req);
- if (err)
- return err;
-
+ memcpy_sglist(req->dst, req->src, req->assoclen);
dst = scatterwalk_ffwd(areq_ctx->dst, req->dst, req->assoclen);
}
@@ -303,7 +283,6 @@
struct crypto_authenc_ctx *ctx = crypto_aead_ctx(tfm);
struct crypto_ahash *auth;
struct crypto_skcipher *enc;
- struct crypto_sync_skcipher *null;
int err;
auth = crypto_spawn_ahash(&ictx->auth);
@@ -315,14 +294,8 @@
if (IS_ERR(enc))
goto err_free_ahash;
- null = crypto_get_default_null_skcipher();
- err = PTR_ERR(null);
- if (IS_ERR(null))
- goto err_free_skcipher;
-
ctx->auth = auth;
ctx->enc = enc;
- ctx->null = null;
crypto_aead_set_reqsize(
tfm,
@@ -336,8 +309,6 @@
return 0;
-err_free_skcipher:
- crypto_free_skcipher(enc);
err_free_ahash:
crypto_free_ahash(auth);
return err;
@@ -349,7 +320,6 @@
crypto_free_ahash(ctx->auth);
crypto_free_skcipher(ctx->enc);
- crypto_put_default_null_skcipher();
}
static void crypto_authenc_free(struct aead_instance *inst)
--- a/crypto/authencesn.c
+++ b/crypto/authencesn.c
@@ -12,7 +12,6 @@
#include <crypto/internal/hash.h>
#include <crypto/internal/skcipher.h>
#include <crypto/authenc.h>
-#include <crypto/null.h>
#include <crypto/scatterwalk.h>
#include <linux/err.h>
#include <linux/init.h>
@@ -31,7 +30,6 @@
unsigned int reqoff;
struct crypto_ahash *auth;
struct crypto_skcipher *enc;
- struct crypto_sync_skcipher *null;
};
struct authenc_esn_request_ctx {
@@ -158,20 +156,6 @@
authenc_esn_request_complete(areq, err);
}
-static int crypto_authenc_esn_copy(struct aead_request *req, unsigned int len)
-{
- struct crypto_aead *authenc_esn = crypto_aead_reqtfm(req);
- struct crypto_authenc_esn_ctx *ctx = crypto_aead_ctx(authenc_esn);
- SYNC_SKCIPHER_REQUEST_ON_STACK(skreq, ctx->null);
-
- skcipher_request_set_sync_tfm(skreq, ctx->null);
- skcipher_request_set_callback(skreq, aead_request_flags(req),
- NULL, NULL);
- skcipher_request_set_crypt(skreq, req->src, req->dst, len, NULL);
-
- return crypto_skcipher_encrypt(skreq);
-}
-
static int crypto_authenc_esn_encrypt(struct aead_request *req)
{
struct crypto_aead *authenc_esn = crypto_aead_reqtfm(req);
@@ -185,15 +169,15 @@
struct scatterlist *src, *dst;
int err;
+ if (assoclen < 8)
+ return -EINVAL;
+
sg_init_table(areq_ctx->src, 2);
src = scatterwalk_ffwd(areq_ctx->src, req->src, assoclen);
dst = src;
if (req->src != req->dst) {
- err = crypto_authenc_esn_copy(req, assoclen);
- if (err)
- return err;
-
+ memcpy_sglist(req->dst, req->src, assoclen);
sg_init_table(areq_ctx->dst, 2);
dst = scatterwalk_ffwd(areq_ctx->dst, req->dst, assoclen);
}
@@ -223,6 +207,7 @@
u8 *ohash = areq_ctx->tail;
unsigned int cryptlen = req->cryptlen - authsize;
unsigned int assoclen = req->assoclen;
+ struct scatterlist *src = req->src;
struct scatterlist *dst = req->dst;
u8 *ihash = ohash + crypto_ahash_digestsize(auth);
u32 tmp[2];
@@ -230,23 +215,29 @@
if (!authsize)
goto decrypt;
- /* Move high-order bits of sequence number back. */
- scatterwalk_map_and_copy(tmp, dst, 4, 4, 0);
- scatterwalk_map_and_copy(tmp + 1, dst, assoclen + cryptlen, 4, 0);
- scatterwalk_map_and_copy(tmp, dst, 0, 8, 1);
+ if (src == dst) {
+ /* Move high-order bits of sequence number back. */
+ scatterwalk_map_and_copy(tmp, dst, 4, 4, 0);
+ scatterwalk_map_and_copy(tmp + 1, dst, assoclen + cryptlen, 4, 0);
+ scatterwalk_map_and_copy(tmp, dst, 0, 8, 1);
+ } else
+ memcpy_sglist(dst, src, assoclen);
if (crypto_memneq(ihash, ohash, authsize))
return -EBADMSG;
decrypt:
- sg_init_table(areq_ctx->dst, 2);
dst = scatterwalk_ffwd(areq_ctx->dst, dst, assoclen);
+ if (req->src == req->dst)
+ src = dst;
+ else
+ src = scatterwalk_ffwd(areq_ctx->src, src, assoclen);
skcipher_request_set_tfm(skreq, ctx->enc);
skcipher_request_set_callback(skreq, flags,
req->base.complete, req->base.data);
- skcipher_request_set_crypt(skreq, dst, dst, cryptlen, req->iv);
+ skcipher_request_set_crypt(skreq, src, dst, cryptlen, req->iv);
return crypto_skcipher_decrypt(skreq);
}
@@ -271,31 +262,36 @@
unsigned int assoclen = req->assoclen;
unsigned int cryptlen = req->cryptlen;
u8 *ihash = ohash + crypto_ahash_digestsize(auth);
+ struct scatterlist *src = req->src;
struct scatterlist *dst = req->dst;
u32 tmp[2];
int err;
- cryptlen -= authsize;
+ if (assoclen < 8)
+ return -EINVAL;
- if (req->src != dst) {
- err = crypto_authenc_esn_copy(req, assoclen + cryptlen);
- if (err)
- return err;
- }
+ if (!authsize)
+ goto tail;
+ cryptlen -= authsize;
scatterwalk_map_and_copy(ihash, req->src, assoclen + cryptlen,
authsize, 0);
- if (!authsize)
- goto tail;
-
/* Move high-order bits of sequence number to the end. */
- scatterwalk_map_and_copy(tmp, dst, 0, 8, 0);
- scatterwalk_map_and_copy(tmp, dst, 4, 4, 1);
- scatterwalk_map_and_copy(tmp + 1, dst, assoclen + cryptlen, 4, 1);
-
- sg_init_table(areq_ctx->dst, 2);
- dst = scatterwalk_ffwd(areq_ctx->dst, dst, 4);
+ scatterwalk_map_and_copy(tmp, src, 0, 8, 0);
+ if (src == dst) {
+ scatterwalk_map_and_copy(tmp, dst, 4, 4, 1);
+ scatterwalk_map_and_copy(tmp + 1, dst, assoclen + cryptlen, 4, 1);
+ dst = scatterwalk_ffwd(areq_ctx->dst, dst, 4);
+ } else {
+ scatterwalk_map_and_copy(tmp, dst, 0, 4, 1);
+ scatterwalk_map_and_copy(tmp + 1, dst, assoclen + cryptlen - 4, 4, 1);
+
+ src = scatterwalk_ffwd(areq_ctx->src, src, 8);
+ dst = scatterwalk_ffwd(areq_ctx->dst, dst, 4);
+ memcpy_sglist(dst, src, assoclen + cryptlen - 8);
+ dst = req->dst;
+ }
ahash_request_set_tfm(ahreq, auth);
ahash_request_set_crypt(ahreq, dst, ohash, assoclen + cryptlen);
@@ -317,7 +313,6 @@
struct crypto_authenc_esn_ctx *ctx = crypto_aead_ctx(tfm);
struct crypto_ahash *auth;
struct crypto_skcipher *enc;
- struct crypto_sync_skcipher *null;
int err;
auth = crypto_spawn_ahash(&ictx->auth);
@@ -329,14 +324,8 @@
if (IS_ERR(enc))
goto err_free_ahash;
- null = crypto_get_default_null_skcipher();
- err = PTR_ERR(null);
- if (IS_ERR(null))
- goto err_free_skcipher;
-
ctx->auth = auth;
ctx->enc = enc;
- ctx->null = null;
ctx->reqoff = 2 * crypto_ahash_digestsize(auth);
@@ -352,8 +341,6 @@
return 0;
-err_free_skcipher:
- crypto_free_skcipher(enc);
err_free_ahash:
crypto_free_ahash(auth);
return err;
@@ -365,7 +352,6 @@
crypto_free_ahash(ctx->auth);
crypto_free_skcipher(ctx->enc);
- crypto_put_default_null_skcipher();
}
static void crypto_authenc_esn_free(struct aead_instance *inst)
--- a/crypto/scatterwalk.c
+++ b/crypto/scatterwalk.c
@@ -69,6 +69,100 @@
}
EXPORT_SYMBOL_GPL(scatterwalk_map_and_copy);
+/**
+ * memcpy_sglist() - Copy data from one scatterlist to another
+ * @dst: The destination scatterlist. Can be NULL if @nbytes == 0.
+ * @src: The source scatterlist. Can be NULL if @nbytes == 0.
+ * @nbytes: Number of bytes to copy
+ *
+ * The scatterlists can describe exactly the same memory, in which case this
+ * function is a no-op. No other overlaps are supported.
+ *
+ * Context: Any context
+ */
+void memcpy_sglist(struct scatterlist *dst, struct scatterlist *src,
+ unsigned int nbytes)
+{
+ unsigned int src_offset, dst_offset;
+
+ if (unlikely(nbytes == 0)) /* in case src and/or dst is NULL */
+ return;
+
+ src_offset = src->offset;
+ dst_offset = dst->offset;
+ for (;;) {
+ /* Compute the length to copy this step. */
+ unsigned int len = min3(src->offset + src->length - src_offset,
+ dst->offset + dst->length - dst_offset,
+ nbytes);
+ struct page *src_page = sg_page(src);
+ struct page *dst_page = sg_page(dst);
+ const void *src_virt;
+ void *dst_virt;
+
+ if (IS_ENABLED(CONFIG_HIGHMEM)) {
+ /* HIGHMEM: we may have to actually map the pages. */
+ const unsigned int src_oip = offset_in_page(src_offset);
+ const unsigned int dst_oip = offset_in_page(dst_offset);
+ const unsigned int limit = PAGE_SIZE;
+
+ /* Further limit len to not cross a page boundary. */
+ len = min3(len, limit - src_oip, limit - dst_oip);
+
+ /* Compute the source and destination pages. */
+ src_page += src_offset / PAGE_SIZE;
+ dst_page += dst_offset / PAGE_SIZE;
+
+ if (src_page != dst_page) {
+ /* Copy between different pages. */
+ memcpy_page(dst_page, dst_oip,
+ src_page, src_oip, len);
+ flush_dcache_page(dst_page);
+ } else if (src_oip != dst_oip) {
+ /* Copy between different parts of same page. */
+ dst_virt = kmap_local_page(dst_page);
+ memcpy(dst_virt + dst_oip, dst_virt + src_oip,
+ len);
+ kunmap_local(dst_virt);
+ flush_dcache_page(dst_page);
+ } /* Else, it's the same memory. No action needed. */
+ } else {
+ /*
+ * !HIGHMEM: no mapping needed. Just work in the linear
+ * buffer of each sg entry. Note that we can cross page
+ * boundaries, as they are not significant in this case.
+ */
+ src_virt = page_address(src_page) + src_offset;
+ dst_virt = page_address(dst_page) + dst_offset;
+ if (src_virt != dst_virt) {
+ memcpy(dst_virt, src_virt, len);
+ if (ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE)
+ __scatterwalk_flush_dcache_pages(
+ dst_page, dst_offset, len);
+ } /* Else, it's the same memory. No action needed. */
+ }
+ nbytes -= len;
+ if (nbytes == 0) /* No more to copy? */
+ break;
+
+ /*
+ * There's more to copy. Advance the offsets by the length
+ * copied this step, and advance the sg entries as needed.
+ */
+ src_offset += len;
+ if (src_offset >= src->offset + src->length) {
+ src = sg_next(src);
+ src_offset = src->offset;
+ }
+ dst_offset += len;
+ if (dst_offset >= dst->offset + dst->length) {
+ dst = sg_next(dst);
+ dst_offset = dst->offset;
+ }
+ }
+}
+EXPORT_SYMBOL_GPL(memcpy_sglist);
+
struct scatterlist *scatterwalk_ffwd(struct scatterlist dst[2],
struct scatterlist *src,
unsigned int len)
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -222,7 +222,6 @@
select CRYPTO_SKCIPHER
select CRYPTO_MANAGER
select CRYPTO_HASH
- select CRYPTO_NULL
help
Authenc: Combined mode wrapper for IPsec.
@@ -1421,7 +1420,6 @@
depends on NET
select CRYPTO_AEAD
select CRYPTO_SKCIPHER
- select CRYPTO_NULL
select CRYPTO_USER_API
help
Enable the userspace interface for AEAD cipher algorithms.
--- a/include/crypto/if_alg.h
+++ b/include/crypto/if_alg.h
@@ -228,9 +228,8 @@
return PAGE_SIZE <= af_alg_rcvbuf(sk);
}
-unsigned int af_alg_count_tsgl(struct sock *sk, size_t bytes, size_t offset);
-void af_alg_pull_tsgl(struct sock *sk, size_t used, struct scatterlist *dst,
- size_t dst_offset);
+unsigned int af_alg_count_tsgl(struct sock *sk, size_t bytes);
+void af_alg_pull_tsgl(struct sock *sk, size_t used, struct scatterlist *dst);
void af_alg_wmem_wakeup(struct sock *sk);
int af_alg_wait_for_data(struct sock *sk, unsigned flags, unsigned min);
int af_alg_sendmsg(struct socket *sock, struct msghdr *msg, size_t size,
--- a/include/crypto/scatterwalk.h
+++ b/include/crypto/scatterwalk.h
@@ -83,6 +83,34 @@
scatterwalk_start(walk, sg_next(walk->sg));
}
+/*
+ * Flush the dcache of any pages that overlap the region
+ * [offset, offset + nbytes) relative to base_page.
+ *
+ * This should be called only when ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE, to ensure
+ * that all relevant code (including the call to sg_page() in the caller, if
+ * applicable) gets fully optimized out when !ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE.
+ */
+static inline void __scatterwalk_flush_dcache_pages(struct page *base_page,
+ unsigned int offset,
+ unsigned int nbytes)
+{
+ unsigned int num_pages;
+
+ base_page += offset / PAGE_SIZE;
+ offset %= PAGE_SIZE;
+
+ /*
+ * This is an overflow-safe version of
+ * num_pages = DIV_ROUND_UP(offset + nbytes, PAGE_SIZE).
+ */
+ num_pages = nbytes / PAGE_SIZE;
+ num_pages += DIV_ROUND_UP(offset + (nbytes % PAGE_SIZE), PAGE_SIZE);
+
+ for (unsigned int i = 0; i < num_pages; i++)
+ flush_dcache_page(base_page + i);
+}
+
static inline void scatterwalk_done(struct scatter_walk *walk, int out,
int more)
{
@@ -94,6 +122,9 @@
void scatterwalk_copychunks(void *buf, struct scatter_walk *walk,
size_t nbytes, int out);
+void memcpy_sglist(struct scatterlist *dst, struct scatterlist *src,
+ unsigned int nbytes);
+
void scatterwalk_map_and_copy(void *buf, struct scatterlist *sg,
unsigned int start, unsigned int nbytes, int out);

View File

@ -1,77 +0,0 @@
From: Andrew Lukoshko <alukoshko@almalinux.org>
Subject: [PATCH AlmaLinux 10] xfrm: esp: avoid in-place decrypt on shared skb frags
Direct cherry-pick of upstream commit f4c50a4034e6 for AlmaLinux 10
(6.12 kernel).
Verified to apply with `patch -p1 -F0` (no offset, no fuzz, no rejects)
against kernel-6.12.0-124.55.1.el10_1.
ESP-in-UDP packets built from MSG_SPLICE_PAGES (pipe pages) look like
ordinary uncloned nonlinear skbs to ESP input, which takes the no-COW
fast path and decrypts in place over data that is not owned privately
by the skb. Mark IPv4/IPv6 datagram splice frags with SKBFL_SHARED_FRAG
matching TCP, and make ESP input fall back to skb_cow_data() when the
flag is present.
Fixes: cac2661c53f3 ("esp4: Avoid skb_cow_data whenever possible")
Fixes: 03e2a30f6a27 ("esp6: Avoid skb_cow_data whenever possible")
Fixes: 7da0dde68486 ("ip, udp: Support MSG_SPLICE_PAGES")
Fixes: 6d8192bd69bb ("ip6, udp6: Support MSG_SPLICE_PAGES")
(cherry picked from commit f4c50a4034e62ab75f1d5cdd191dd5f9c77fdff4)
Signed-off-by: Andrew Lukoshko <alukoshko@almalinux.org>
---
net/ipv4/esp4.c | 3 ++-
net/ipv4/ip_output.c | 2 ++
net/ipv6/esp6.c | 3 ++-
net/ipv6/ip6_output.c | 2 ++
4 files changed, 8 insertions(+), 2 deletions(-)
--- a/net/ipv4/esp4.c
+++ b/net/ipv4/esp4.c
@@ -908,7 +908,8 @@
nfrags = 1;
goto skip_cow;
- } else if (!skb_has_frag_list(skb)) {
+ } else if (!skb_has_frag_list(skb) &&
+ !skb_has_shared_frag(skb)) {
nfrags = skb_shinfo(skb)->nr_frags;
nfrags++;
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -1236,6 +1236,8 @@
if (err < 0)
goto error;
copy = err;
+ if (!(flags & MSG_NO_SHARED_FRAGS))
+ skb_shinfo(skb)->flags |= SKBFL_SHARED_FRAG;
wmem_alloc_delta += copy;
} else if (!zc) {
int i = skb_shinfo(skb)->nr_frags;
--- a/net/ipv6/esp6.c
+++ b/net/ipv6/esp6.c
@@ -950,7 +950,8 @@
nfrags = 1;
goto skip_cow;
- } else if (!skb_has_frag_list(skb)) {
+ } else if (!skb_has_frag_list(skb) &&
+ !skb_has_shared_frag(skb)) {
nfrags = skb_shinfo(skb)->nr_frags;
nfrags++;
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -1769,6 +1769,8 @@
if (err < 0)
goto error;
copy = err;
+ if (!(flags & MSG_NO_SHARED_FRAGS))
+ skb_shinfo(skb)->flags |= SKBFL_SHARED_FRAG;
wmem_alloc_delta += copy;
} else if (!zc) {
int i = skb_shinfo(skb)->nr_frags;
--
2.43.0

View File

@ -1,69 +0,0 @@
From: Andrew Lukoshko <alukoshko@almalinux.org>
Subject: [PATCH AlmaLinux 10] rxrpc: linearize incoming DATA packet when it has paged frags
AlmaLinux-specific backport of the intent of the upstream rxrpc fix
posted at https://lore.kernel.org/all/afKV2zGR6rrelPC7@v4bel/ for the
"Dirty Frag" class of bugs (sibling to upstream commit f4c50a4034e6 in
the ESP/xfrm subsystem).
The upstream patch can not be cherry-picked against this 6.12 tree:
its target lines were introduced by upstream commit d0d5c0cd1e71
("rxrpc: Use skb_unshare() rather than skb_cow_data()") which is not
present here. The age-equivalent code path on AlmaLinux 10 is the
centralized skb_unshare() in net/rxrpc/io_thread.c that is run for
every DATA packet with a non-zero securityIndex before in-place
decryption.
skb_unshare() only handles cloned skbs. An skb that is non-cloned but
carries paged fragments (skb->data_len != 0) — e.g. pages attached via
udp_sendpage() / splice() / MSG_SPLICE_PAGES on a UDP socket carrying
rxrpc traffic — slips through and is decrypted in place over data the
skb does not own privately. With kernel-modules-partner installed
(rxrpc.ko enabled), this is exploitable.
Replace the unconditional skb_unshare() with skb_copy() whenever the
skb is cloned OR carries paged fragments. skb_copy() always returns a
freshly allocated linear skb, so subsequent in-place decryption only
touches kernel-owned memory. The original skb is consumed explicitly
(skb_unshare did this internally via consume_skb()).
Verified to apply with `patch -p1 -F0` (no offset, no fuzz, no
rejects) against kernel-6.12.0-124.55.1.el10_1.
Fixes: cac2661c53f3 ("rxrpc: Use skb_cow_data() in rxrpc_recvmsg_data()")
Signed-off-by: Andrew Lukoshko <alukoshko@almalinux.org>
---
net/rxrpc/io_thread.c | 18 ++++++++++--------
1 file changed, 10 insertions(+), 8 deletions(-)
--- a/net/rxrpc/io_thread.c
+++ b/net/rxrpc/io_thread.c
@@ -235,16 +235,18 @@
* decryption.
*/
if (sp->hdr.securityIndex != 0) {
- skb = skb_unshare(skb, GFP_ATOMIC);
- if (!skb) {
- rxrpc_eaten_skb(*_skb, rxrpc_skb_eaten_by_unshare_nomem);
- *_skb = NULL;
- return just_discard;
- }
+ if (skb_cloned(skb) || skb->data_len) {
+ struct sk_buff *nskb = skb_copy(skb, GFP_ATOMIC);
+
+ if (!nskb) {
+ rxrpc_eaten_skb(*_skb, rxrpc_skb_eaten_by_unshare_nomem);
+ return just_discard;
+ }
- if (skb != *_skb) {
rxrpc_eaten_skb(*_skb, rxrpc_skb_eaten_by_unshare);
- *_skb = skb;
+ consume_skb(*_skb);
+ *_skb = nskb;
+ skb = nskb;
rxrpc_new_skb(skb, rxrpc_skb_new_unshared);
sp = rxrpc_skb(skb);
}
--
2.43.0

View File

@ -1,147 +0,0 @@
From: Andrew Lukoshko <alukoshko@almalinux.org>
Subject: [PATCH AlmaLinux 10] net: skbuff: propagate shared-frag marker through frag-transfer helpers
Backport of upstream v5 patch posted at
https://lore.kernel.org/all/ageeJfJHwgzmKXbh@v4bel/
(sibling to upstream commit f4c50a4034e6 "xfrm: esp: avoid in-place
decrypt on shared skb frags").
Three frag-transfer helpers in net/core/skbuff.c
(__pskb_copy_fclone(), skb_try_coalesce(), skb_shift()) and the two
GRO accumulator helpers in net/core/gro.c (skb_gro_receive() and
skb_gro_receive_list()) fail to propagate the SKBFL_SHARED_FRAG bit
in skb_shinfo()->flags when moving frag descriptors from source to
destination. In addition, skb_segment() folds only head_skb's flag
into nskb on the per-iteration flag merge, and the inner switch that
rebinds frag_skb to list_skb on head_skb-frags exhaustion does not
fold the new frag_skb's flag into nskb. Finally,
tcp_clone_payload() builds an MTU probe skb by moving frag
descriptors from sk_write_queue skbs into a fresh nskb without
propagating the marker. As a result, the destination skb keeps a
reference to the same externally-owned or page-cache-backed pages
while reporting skb_has_shared_frag() as false.
The mismatch is harmful in any in-place writer that uses
skb_has_shared_frag() to decide whether shared pages must be detoured
through skb_cow_data(). ESP input is one such writer (esp4.c,
esp6.c). Combined with an nft 'dup to <local>' rule, an
nf_dup_ipv4() / xt_TEE caller, or ESP-over-UDP with UDP GRO, this
lets an unprivileged user write into the page cache of a root-owned
read-only file via authencesn-ESN stray writes (CVE-2026-46300,
"Fragnesia").
Set SKBFL_SHARED_FRAG on the destination whenever frag descriptors
were actually moved from the source. skb_copy() and skb_copy_expand()
share skb_copy_header() too but linearize all paged data into freshly
allocated head storage and emerge with nr_frags == 0, so
skb_has_shared_frag() returns false on its own; they need no change.
The same omission exists in skb_gro_receive() and
skb_gro_receive_list(). The former moves the incoming skb's frag
descriptors into the accumulator's last sub-skb via two paths plus a
"merge:" fallback that chains the whole skb onto frag_list; the
latter chains the incoming skb whole onto p's frag_list. Downstream
skb_segment() reads only skb_shinfo(p)->flags, and skb_segment_list()
reuses each sub-skb's shinfo as the nskb -- both p and lp must carry
the marker.
skb_try_coalesce() hunk: upstream v5 drops the v3/v4 skb_try_coalesce()
change because commit f84eca581739 ("net: account for SKBFL_SHARED_FRAG
in skb_split() and skb_try_coalesce()") covers that site there. Only
the skb_split() half of f84eca581739 is currently backported in 6.12,
so the skb_try_coalesce() hunk is retained here to close the same gap.
Fixes: cef401de7be8 ("net: fix possible wrong checksum generation")
Fixes: f4c50a4034e6 ("xfrm: esp: avoid in-place decrypt on shared skb frags")
Reported-by: Sultan Alsawaf <sultan@kerneltoast.com>
Reported-by: William Bowling <vakzz@zellic.io>
Reported-by: Hyunwoo Kim <imv4bel@gmail.com>
Signed-off-by: Andrew Lukoshko <alukoshko@almalinux.org>
---
net/core/gro.c | 4 ++++
net/core/skbuff.c | 14 +++++++++++++-
net/ipv4/tcp_output.c | 1 +
3 files changed, 18 insertions(+), 1 deletion(-)
--- a/net/core/skbuff.c 2026-05-28 13:12:16.410047140 +0200
+++ b/net/core/skbuff.c 2026-05-28 13:17:15.081411917 +0200
@@ -2123,6 +2123,7 @@
skb_frag_ref(skb, i);
}
skb_shinfo(n)->nr_frags = i;
+ skb_shinfo(n)->flags |= skb_shinfo(skb)->flags & SKBFL_SHARED_FRAG;
}
if (skb_has_frag_list(skb)) {
@@ -4198,6 +4199,8 @@
tgt->ip_summed = CHECKSUM_PARTIAL;
skb->ip_summed = CHECKSUM_PARTIAL;
+ skb_shinfo(tgt)->flags |= skb_shinfo(skb)->flags & SKBFL_SHARED_FRAG;
+
skb_len_add(skb, -shiftlen);
skb_len_add(tgt, shiftlen);
@@ -4808,7 +4811,8 @@
skb_copy_from_linear_data_offset(head_skb, offset,
skb_put(nskb, hsize), hsize);
- skb_shinfo(nskb)->flags |= skb_shinfo(head_skb)->flags &
+ skb_shinfo(nskb)->flags |= (skb_shinfo(head_skb)->flags |
+ skb_shinfo(frag_skb)->flags) &
SKBFL_SHARED_FRAG;
if (skb_zerocopy_clone(nskb, frag_skb, GFP_ATOMIC))
@@ -4825,6 +4829,9 @@
nfrags = skb_shinfo(list_skb)->nr_frags;
frag = skb_shinfo(list_skb)->frags;
frag_skb = list_skb;
+
+ skb_shinfo(nskb)->flags |= skb_shinfo(frag_skb)->flags & SKBFL_SHARED_FRAG;
+
if (!skb_headlen(list_skb)) {
BUG_ON(!nfrags);
} else {
@@ -6030,6 +6037,8 @@
from_shinfo->frags,
from_shinfo->nr_frags * sizeof(skb_frag_t));
to_shinfo->nr_frags += from_shinfo->nr_frags;
+ if (from_shinfo->nr_frags)
+ to_shinfo->flags |= from_shinfo->flags & SKBFL_SHARED_FRAG;
if (!skb_cloned(from))
from_shinfo->nr_frags = 0;
--- a/net/core/gro.c 2026-05-28 13:12:16.409094447 +0200
+++ b/net/core/gro.c 2026-05-28 13:15:11.599892601 +0200
@@ -214,10 +214,12 @@
p->data_len += len;
p->truesize += delta_truesize;
p->len += len;
+ skb_shinfo(p)->flags |= skbinfo->flags & SKBFL_SHARED_FRAG;
if (lp != p) {
lp->data_len += len;
lp->truesize += delta_truesize;
lp->len += len;
+ skb_shinfo(lp)->flags |= skbinfo->flags & SKBFL_SHARED_FRAG;
}
NAPI_GRO_CB(skb)->same_flow = 1;
return 0;
@@ -245,6 +247,8 @@
p->truesize += skb->truesize;
p->len += skb->len;
+ skb_shinfo(p)->flags |= skb_shinfo(skb)->flags & SKBFL_SHARED_FRAG;
+
NAPI_GRO_CB(skb)->same_flow = 1;
return 0;
--- a/net/ipv4/tcp_output.c 2026-05-28 13:12:16.846070054 +0200
+++ b/net/ipv4/tcp_output.c 2026-05-28 13:14:19.646400034 +0200
@@ -2380,6 +2380,7 @@
todo = min_t(int, skb_frag_size(fragfrom),
probe_size - len);
len += todo;
+ skb_shinfo(to)->flags |= skb_shinfo(skb)->flags & SKBFL_SHARED_FRAG;
if (lastfrag &&
skb_frag_page(fragfrom) == skb_frag_page(lastfrag) &&
skb_frag_off(fragfrom) == skb_frag_off(lastfrag) +

View File

@ -1,55 +0,0 @@
From: Andrew Lukoshko <alukoshko@almalinux.org>
Subject: [PATCH AlmaLinux 10] ptrace: require CAP_SYS_PTRACE when task has no mm
kABI-safe AlmaLinux backport of upstream commit 31e62c2ebbfd
("ptrace: slightly saner 'get_dumpable()' logic") posted at
https://github.com/torvalds/linux/commit/31e62c2ebbfdc3fe3dbdf5e02c92a9dc67087a3a
The upstream fix adds a 'user_dumpable:1' bit to task_struct and
caches the last dumpability in exit_mm() so __ptrace_may_access()
can require CAP_SYS_PTRACE when the target has no mm (e.g. kernel
threads or already-exited user tasks). That layout change to
task_struct breaks kABI on AlmaLinux 10 (the symtype
signature of struct task_struct is referenced by hundreds of
stablelist exports), so we cannot import the field/exit_mm hunks
as-is.
Take the minimal kABI-safe slice instead: when task->mm == NULL,
require CAP_SYS_PTRACE in init_user_ns unconditionally. This closes
the Qualys Security Advisory hole -- mm-less targets no longer pass
the dumpability check by default -- without touching task_struct or
exit.c. The only behavioural delta versus upstream is that a user
task that has already cleared its mm in exit_mm() (a dying/zombie
task) now also requires CAP_SYS_PTRACE to attach, instead of being
remembered as previously dumpable. Such targets are rarely ptraced
in practice.
Verified to apply with `patch -p1 -F0` (no offset, no fuzz, no rejects)
against kernel-6.12.0-124.56.1.el10_1.
Reported-by: Qualys Security Advisory <qsa@qualys.com>
Signed-off-by: Andrew Lukoshko <alukoshko@almalinux.org>
---
kernel/ptrace.c | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
--- a/kernel/ptrace.c
+++ b/kernel/ptrace.c
@@ -339,8 +339,11 @@ static int __ptrace_may_access(struct task_struct *task, unsigned int mode)
smp_rmb();
mm = task->mm;
- if (mm &&
- ((get_dumpable(mm) != SUID_DUMP_USER) &&
- !ptrace_has_cap(mm->user_ns, mode)))
- return -EPERM;
+ if (mm) {
+ if ((get_dumpable(mm) != SUID_DUMP_USER) &&
+ !ptrace_has_cap(mm->user_ns, mode))
+ return -EPERM;
+ } else if (!ptrace_has_cap(&init_user_ns, mode)) {
+ return -EPERM;
+ }
return security_ptrace_access_check(task, mode);
--
2.43.0

View File

@ -0,0 +1,89 @@
From ff57186b2cc39766672c4c0332323933e5faaa88 Mon Sep 17 00:00:00 2001
From: William Liu <will@willsroot.io>
Date: Tue, 19 Aug 2025 03:36:28 +0000
Subject: [PATCH] net/sched: Make cake_enqueue return NET_XMIT_CN when past
buffer_limit
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
[ Upstream commit 15de71d06a400f7fdc15bf377a2552b0ec437cf5 ]
The following setup can trigger a WARNING in htb_activate due to
the condition: !cl->leaf.q->q.qlen
tc qdisc del dev lo root
tc qdisc add dev lo root handle 1: htb default 1
tc class add dev lo parent 1: classid 1:1 \
htb rate 64bit
tc qdisc add dev lo parent 1:1 handle f: \
cake memlimit 1b
ping -I lo -f -c1 -s64 -W0.001 127.0.0.1
This is because the low memlimit leads to a low buffer_limit, which
causes packet dropping. However, cake_enqueue still returns
NET_XMIT_SUCCESS, causing htb_enqueue to call htb_activate with an
empty child qdisc. We should return NET_XMIT_CN when packets are
dropped from the same tin and flow.
I do not believe return value of NET_XMIT_CN is necessary for packet
drops in the case of ack filtering, as that is meant to optimize
performance, not to signal congestion.
Fixes: 046f6fd5daef ("sched: Add Common Applications Kept Enhanced (cake) qdisc")
Signed-off-by: William Liu <will@willsroot.io>
Reviewed-by: Savino Dicanosa <savy@syst3mfailure.io>
Acked-by: Toke Høiland-Jørgensen <toke@toke.dk>
Reviewed-by: Jamal Hadi Salim <jhs@mojatatu.com>
Link: https://patch.msgid.link/20250819033601.579821-1-will@willsroot.io
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
diff --git a/net/sched/sch_cake.c b/net/sched/sch_cake.c
index 2c2e2a67f3b2..6cbe8a7a0e5c 100644
--- a/net/sched/sch_cake.c
+++ b/net/sched/sch_cake.c
@@ -1745,7 +1745,7 @@ static s32 cake_enqueue(struct sk_buff *skb, struct Qdisc *sch,
ktime_t now = ktime_get();
struct cake_tin_data *b;
struct cake_flow *flow;
- u32 idx;
+ u32 idx, tin;
/* choose flow to insert into */
idx = cake_classify(sch, &b, skb, q->flow_mode, &ret);
@@ -1755,6 +1755,7 @@ static s32 cake_enqueue(struct sk_buff *skb, struct Qdisc *sch,
__qdisc_drop(skb, to_free);
return ret;
}
+ tin = (u32)(b - q->tins);
idx--;
flow = &b->flows[idx];
@@ -1922,13 +1923,22 @@ static s32 cake_enqueue(struct sk_buff *skb, struct Qdisc *sch,
q->buffer_max_used = q->buffer_used;
if (q->buffer_used > q->buffer_limit) {
+ bool same_flow = false;
u32 dropped = 0;
+ u32 drop_id;
while (q->buffer_used > q->buffer_limit) {
dropped++;
- cake_drop(sch, to_free);
+ drop_id = cake_drop(sch, to_free);
+
+ if ((drop_id >> 16) == tin &&
+ (drop_id & 0xFFFF) == idx)
+ same_flow = true;
}
b->drop_overlimit += dropped;
+
+ if (same_flow)
+ return NET_XMIT_CN;
}
return NET_XMIT_SUCCESS;
}
--
2.50.1 (Apple Git-155)

View File

@ -0,0 +1,118 @@
diff --git a/net/sched/sch_cake.c b/net/sched/sch_cake.c
index aa9f31e..ef51a9e 100644
--- a/net/sched/sch_cake.c
+++ b/net/sched/sch_cake.c
@@ -1594,7 +1594,6 @@ static unsigned int cake_drop(struct Qdisc *sch, struct sk_buff **to_free)
qdisc_drop_reason(skb, sch, to_free, SKB_DROP_REASON_QDISC_OVERLIMIT);
sch->q.qlen--;
- qdisc_tree_reduce_backlog(sch, 1, len);
cake_heapify(q, 0);
@@ -1740,14 +1739,14 @@ static void cake_reconfigure(struct Qdisc *sch);
static s32 cake_enqueue(struct sk_buff *skb, struct Qdisc *sch,
struct sk_buff **to_free)
{
+ u32 idx, tin, prev_qlen, prev_backlog, drop_id;
struct cake_sched_data *q = qdisc_priv(sch);
- int len = qdisc_pkt_len(skb);
- int ret;
+ int len = qdisc_pkt_len(skb), ret;
struct sk_buff *ack = NULL;
ktime_t now = ktime_get();
struct cake_tin_data *b;
struct cake_flow *flow;
- u32 idx, tin;
+ bool same_flow = false;
/* choose flow to insert into */
idx = cake_classify(sch, &b, skb, q->flow_mode, &ret);
@@ -1820,6 +1819,8 @@ static s32 cake_enqueue(struct sk_buff *skb, struct Qdisc *sch,
consume_skb(skb);
} else {
/* not splitting */
+ int ack_pkt_len = 0;
+
cobalt_set_enqueue_time(skb, now);
get_cobalt_cb(skb)->adjusted_len = cake_overhead(q, skb);
flow_queue_add(flow, skb);
@@ -1830,13 +1831,13 @@ static s32 cake_enqueue(struct sk_buff *skb, struct Qdisc *sch,
if (ack) {
b->ack_drops++;
sch->qstats.drops++;
- b->bytes += qdisc_pkt_len(ack);
- len -= qdisc_pkt_len(ack);
+ ack_pkt_len = qdisc_pkt_len(ack);
+ b->bytes += ack_pkt_len;
q->buffer_used += skb->truesize - ack->truesize;
if (q->rate_flags & CAKE_FLAG_INGRESS)
cake_advance_shaper(q, b, ack, now, true);
- qdisc_tree_reduce_backlog(sch, 1, qdisc_pkt_len(ack));
+ qdisc_tree_reduce_backlog(sch, 1, ack_pkt_len);
consume_skb(ack);
} else {
sch->q.qlen++;
@@ -1845,11 +1846,11 @@ static s32 cake_enqueue(struct sk_buff *skb, struct Qdisc *sch,
/* stats */
b->packets++;
- b->bytes += len;
- b->backlogs[idx] += len;
- b->tin_backlog += len;
- sch->qstats.backlog += len;
- q->avg_window_bytes += len;
+ b->bytes += len - ack_pkt_len;
+ b->backlogs[idx] += len - ack_pkt_len;
+ b->tin_backlog += len - ack_pkt_len;
+ sch->qstats.backlog += len - ack_pkt_len;
+ q->avg_window_bytes += len - ack_pkt_len;
}
if (q->overflow_timeout)
@@ -1924,24 +1925,29 @@ static s32 cake_enqueue(struct sk_buff *skb, struct Qdisc *sch,
if (q->buffer_used > q->buffer_max_used)
q->buffer_max_used = q->buffer_used;
- if (q->buffer_used > q->buffer_limit) {
- bool same_flow = false;
- u32 dropped = 0;
- u32 drop_id;
+ if (q->buffer_used <= q->buffer_limit)
+ return NET_XMIT_SUCCESS;
- while (q->buffer_used > q->buffer_limit) {
- dropped++;
- drop_id = cake_drop(sch, to_free);
+ prev_qlen = sch->q.qlen;
+ prev_backlog = sch->qstats.backlog;
- if ((drop_id >> 16) == tin &&
- (drop_id & 0xFFFF) == idx)
- same_flow = true;
- }
- b->drop_overlimit += dropped;
+ while (q->buffer_used > q->buffer_limit) {
+ drop_id = cake_drop(sch, to_free);
+ if ((drop_id >> 16) == tin &&
+ (drop_id & 0xFFFF) == idx)
+ same_flow = true;
+ }
+
+ prev_qlen -= sch->q.qlen;
+ prev_backlog -= sch->qstats.backlog;
+ b->drop_overlimit += prev_qlen;
- if (same_flow)
- return NET_XMIT_CN;
+ if (same_flow) {
+ qdisc_tree_reduce_backlog(sch, prev_qlen - 1,
+ prev_backlog - len);
+ return NET_XMIT_CN;
}
+ qdisc_tree_reduce_backlog(sch, prev_qlen, prev_backlog);
return NET_XMIT_SUCCESS;
}

View File

@ -0,0 +1,61 @@
From cd7786466db3f8e0004e2383a066b3c805643196 Mon Sep 17 00:00:00 2001
From: Sreekanth Reddy <sreeredd@redhat.com>
Date: Fri, 8 Aug 2025 15:41:46 -0700
Subject: [PATCH] RDMA/bnxt_re: Support extended stats for Thor2 VF
JIRA: https://issues.redhat.com/browse/RHEL-108694
commit 260ce16e579d375ba8f1ac945308343522f98d50
Author: Ajit Khaparde <ajit.khaparde@broadcom.com>
Date: Fri May 23 13:29:52 2025 +0530
RDMA/bnxt_re: Support extended stats for Thor2 VF
The driver currently checks if the user is querying VF RoCE statistics.
It will not send the query_roce_stats_ext HWRM command if it is for a
VF. But Thor2 VF can support extended statistics.
Allow query of extended stats for Thor2 VFs.
Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
Signed-off-by: Shravya KN <shravya.k-n@broadcom.com>
Link: https://patch.msgid.link/20250523075952.1267827-1-kalesh-anakkur.purayil@broadcom.com
Reviewed-by: Damodharam Ammepalli <damodharam.ammepalli@broadcom.com>
Reviewed-by: Kalesh AP <kalesh-anakkur.purayil@broadcom.com>
Signed-off-by: Leon Romanovsky <leon@kernel.org>
Signed-off-by: Sreekanth Reddy <sreeredd@redhat.com>
diff --git a/drivers/infiniband/hw/bnxt_re/qplib_fp.c b/drivers/infiniband/hw/bnxt_re/qplib_fp.c
index 457eecb99f96..be34c605d516 100644
--- a/drivers/infiniband/hw/bnxt_re/qplib_fp.c
+++ b/drivers/infiniband/hw/bnxt_re/qplib_fp.c
@@ -1113,7 +1113,7 @@ int bnxt_qplib_create_qp(struct bnxt_qplib_res *res, struct bnxt_qplib_qp *qp)
qp_flags |= CMDQ_CREATE_QP_QP_FLAGS_FORCE_COMPLETION;
if (qp->wqe_mode == BNXT_QPLIB_WQE_MODE_VARIABLE)
qp_flags |= CMDQ_CREATE_QP_QP_FLAGS_VARIABLE_SIZED_WQE_ENABLED;
- if (_is_ext_stats_supported(res->dattr->dev_cap_flags) && !res->is_vf)
+ if (bnxt_ext_stats_supported(res->cctx, res->dattr->dev_cap_flags, res->is_vf))
qp_flags |= CMDQ_CREATE_QP_QP_FLAGS_EXT_STATS_ENABLED;
req.qp_flags = cpu_to_le32(qp_flags);
diff --git a/drivers/infiniband/hw/bnxt_re/qplib_sp.c b/drivers/infiniband/hw/bnxt_re/qplib_sp.c
index f231e886ad9d..9efd32a3dc55 100644
--- a/drivers/infiniband/hw/bnxt_re/qplib_sp.c
+++ b/drivers/infiniband/hw/bnxt_re/qplib_sp.c
@@ -846,7 +846,12 @@ int bnxt_qplib_qext_stat(struct bnxt_qplib_rcfw *rcfw, u32 fid,
req.resp_size = sbuf.size / BNXT_QPLIB_CMDQE_UNITS;
req.resp_addr = cpu_to_le64(sbuf.dma_addr);
- req.function_id = cpu_to_le32(fid);
+ if (bnxt_qplib_is_chip_gen_p7(rcfw->res->cctx) && rcfw->res->is_vf)
+ req.function_id =
+ cpu_to_le32(CMDQ_QUERY_ROCE_STATS_EXT_VF_VALID |
+ (fid << CMDQ_QUERY_ROCE_STATS_EXT_VF_NUM_SFT));
+ else
+ req.function_id = cpu_to_le32(fid);
req.flags = cpu_to_le16(CMDQ_QUERY_ROCE_STATS_EXT_FLAGS_FUNCTION_ID);
bnxt_qplib_fill_cmdqmsg(&msg, &req, &resp, &sbuf, sizeof(req),
--
2.50.1 (Apple Git-155)

View File

@ -0,0 +1,41 @@
From b66389e5f1dea3e149fdf089036021e5ab3fc52d Mon Sep 17 00:00:00 2001
From: Sreekanth Reddy <sreeredd@redhat.com>
Date: Fri, 8 Aug 2025 15:43:05 -0700
Subject: [PATCH] RDMA/bnxt_re: Fix size of uverbs_copy_to() in
BNXT_RE_METHOD_GET_TOGGLE_MEM
JIRA: https://issues.redhat.com/browse/RHEL-108694
commit 09d231ab569ca97478445ccc1ad44ab026de39b1
Author: Kalesh AP <kalesh-anakkur.purayil@broadcom.com>
Date: Fri Jul 4 10:08:55 2025 +0530
RDMA/bnxt_re: Fix size of uverbs_copy_to() in BNXT_RE_METHOD_GET_TOGGLE_MEM
Since both "length" and "offset" are of type u32, there is
no functional issue here.
Reviewed-by: Saravanan Vajravel <saravanan.vajravel@broadcom.com>
Signed-off-by: Shravya KN <shravya.k-n@broadcom.com>
Signed-off-by: Kalesh AP <kalesh-anakkur.purayil@broadcom.com>
Link: https://patch.msgid.link/20250704043857.19158-2-kalesh-anakkur.purayil@broadcom.com
Signed-off-by: Leon Romanovsky <leon@kernel.org>
Signed-off-by: Sreekanth Reddy <sreeredd@redhat.com>
diff --git a/drivers/infiniband/hw/bnxt_re/ib_verbs.c b/drivers/infiniband/hw/bnxt_re/ib_verbs.c
index 063801384b2b..3a627acb82ce 100644
--- a/drivers/infiniband/hw/bnxt_re/ib_verbs.c
+++ b/drivers/infiniband/hw/bnxt_re/ib_verbs.c
@@ -4738,7 +4738,7 @@ static int UVERBS_HANDLER(BNXT_RE_METHOD_GET_TOGGLE_MEM)(struct uverbs_attr_bund
return err;
err = uverbs_copy_to(attrs, BNXT_RE_TOGGLE_MEM_MMAP_OFFSET,
- &offset, sizeof(length));
+ &offset, sizeof(offset));
if (err)
return err;
--
2.50.1 (Apple Git-155)

View File

@ -0,0 +1,127 @@
From 36c9223728944bf2e60709bd6c233c9bc0d1b56e Mon Sep 17 00:00:00 2001
From: Sreekanth Reddy <sreeredd@redhat.com>
Date: Fri, 8 Aug 2025 15:43:19 -0700
Subject: [PATCH] RDMA/bnxt_re: Support 2G message size
JIRA: https://issues.redhat.com/browse/RHEL-108694
commit 0aed817380d620987b2d5c573fdd2f01c30976a4
Author: Selvin Xavier <selvin.xavier@broadcom.com>
Date: Fri Jul 4 10:08:56 2025 +0530
RDMA/bnxt_re: Support 2G message size
bnxt_qplib_put_sges is calculating the length in
a signed int. So handling the 2G message size
is not working since it is considered as negative.
Use a unsigned number to calculate the total message
length. As per the spec, IB message size shall be
between zero and 2^31 bytes (inclusive). So adding
a check for 2G message size.
Signed-off-by: Selvin Xavier <selvin.xavier@broadcom.com>
Signed-off-by: Shravya KN <shravya.k-n@broadcom.com>
Link: https://patch.msgid.link/20250704043857.19158-3-kalesh-anakkur.purayil@broadcom.com
Reviewed-by: Saravanan Vajravel <saravanan.vajravel@broadcom.com>
Reviewed-by: Kalesh AP <kalesh-anakkur.purayil@broadcom.com>
Signed-off-by: Leon Romanovsky <leon@kernel.org>
Signed-off-by: Sreekanth Reddy <sreeredd@redhat.com>
diff --git a/drivers/infiniband/hw/bnxt_re/qplib_fp.c b/drivers/infiniband/hw/bnxt_re/qplib_fp.c
index be34c605d516..dfe3177123e5 100644
--- a/drivers/infiniband/hw/bnxt_re/qplib_fp.c
+++ b/drivers/infiniband/hw/bnxt_re/qplib_fp.c
@@ -1750,9 +1750,9 @@ static void bnxt_qplib_fill_psn_search(struct bnxt_qplib_qp *qp,
}
}
-static int bnxt_qplib_put_inline(struct bnxt_qplib_qp *qp,
- struct bnxt_qplib_swqe *wqe,
- u16 *idx)
+static unsigned int bnxt_qplib_put_inline(struct bnxt_qplib_qp *qp,
+ struct bnxt_qplib_swqe *wqe,
+ u32 *idx)
{
struct bnxt_qplib_hwq *hwq;
int len, t_len, offt;
@@ -1769,7 +1769,7 @@ static int bnxt_qplib_put_inline(struct bnxt_qplib_qp *qp,
il_src = (void *)wqe->sg_list[indx].addr;
t_len += len;
if (t_len > qp->max_inline_data)
- return -ENOMEM;
+ return BNXT_RE_INVAL_MSG_SIZE;
while (len) {
if (pull_dst) {
pull_dst = false;
@@ -1795,9 +1795,9 @@ static int bnxt_qplib_put_inline(struct bnxt_qplib_qp *qp,
return t_len;
}
-static u32 bnxt_qplib_put_sges(struct bnxt_qplib_hwq *hwq,
- struct bnxt_qplib_sge *ssge,
- u16 nsge, u16 *idx)
+static unsigned int bnxt_qplib_put_sges(struct bnxt_qplib_hwq *hwq,
+ struct bnxt_qplib_sge *ssge,
+ u32 nsge, u32 *idx)
{
struct sq_sge *dsge;
int indx, len = 0;
@@ -1878,14 +1878,12 @@ int bnxt_qplib_post_send(struct bnxt_qplib_qp *qp,
struct bnxt_qplib_hwq *hwq;
struct bnxt_qplib_swq *swq;
bool sch_handler = false;
+ u32 wqe_idx, slots, idx;
u16 wqe_sz, qdf = 0;
bool msn_update;
void *base_hdr;
void *ext_hdr;
__le32 temp32;
- u32 wqe_idx;
- u32 slots;
- u16 idx;
hwq = &sq->hwq;
if (qp->state != CMDQ_MODIFY_QP_NEW_STATE_RTS &&
@@ -1937,8 +1935,10 @@ int bnxt_qplib_post_send(struct bnxt_qplib_qp *qp,
else
data_len = bnxt_qplib_put_sges(hwq, wqe->sg_list, wqe->num_sge,
&idx);
- if (data_len < 0)
- goto queue_err;
+ if (data_len > BNXT_RE_MAX_MSG_SIZE) {
+ rc = -EINVAL;
+ goto done;
+ }
/* Make sure we update MSN table only for wired wqes */
msn_update = true;
/* Specifics */
@@ -2139,8 +2139,8 @@ int bnxt_qplib_post_recv(struct bnxt_qplib_qp *qp,
struct bnxt_qplib_hwq *hwq;
struct bnxt_qplib_swq *swq;
bool sch_handler = false;
- u16 wqe_sz, idx;
- u32 wqe_idx;
+ u32 wqe_idx, idx;
+ u16 wqe_sz;
int rc = 0;
hwq = &rq->hwq;
diff --git a/drivers/infiniband/hw/bnxt_re/qplib_fp.h b/drivers/infiniband/hw/bnxt_re/qplib_fp.h
index 0d9487c889ff..ab125f1d949e 100644
--- a/drivers/infiniband/hw/bnxt_re/qplib_fp.h
+++ b/drivers/infiniband/hw/bnxt_re/qplib_fp.h
@@ -346,6 +346,9 @@ struct bnxt_qplib_qp {
u8 tos_dscp;
};
+#define BNXT_RE_MAX_MSG_SIZE 0x80000000
+#define BNXT_RE_INVAL_MSG_SIZE 0xFFFFFFFF
+
#define BNXT_QPLIB_MAX_CQE_ENTRY_SIZE sizeof(struct cq_base)
#define CQE_CNT_PER_PG (PAGE_SIZE / BNXT_QPLIB_MAX_CQE_ENTRY_SIZE)
--
2.50.1 (Apple Git-155)

View File

@ -0,0 +1,53 @@
From c610161ea1b9940dbfa17cbab72bf8c945145dea Mon Sep 17 00:00:00 2001
From: Sreekanth Reddy <sreeredd@redhat.com>
Date: Fri, 8 Aug 2025 15:43:30 -0700
Subject: [PATCH] RDMA/bnxt_re: Use macro instead of hard coded value
JIRA: https://issues.redhat.com/browse/RHEL-108694
commit 7788278ff267f831bab39a377beaa7e08d79c2a9
Author: Kalesh AP <kalesh-anakkur.purayil@broadcom.com>
Date: Fri Jul 4 10:08:57 2025 +0530
RDMA/bnxt_re: Use macro instead of hard coded value
1. Defined a macro for the hard coded value.
2. "access" field in the request structure is of type "u8".
Updated the mask accordingly.
Signed-off-by: Kalesh AP <kalesh-anakkur.purayil@broadcom.com>
Signed-off-by: Shravya KN <shravya.k-n@broadcom.com>
Link: https://patch.msgid.link/20250704043857.19158-4-kalesh-anakkur.purayil@broadcom.com
Reviewed-by: Hongguang Gao <hongguang.gao@broadcom.com>
Signed-off-by: Leon Romanovsky <leon@kernel.org>
Signed-off-by: Sreekanth Reddy <sreeredd@redhat.com>
diff --git a/drivers/infiniband/hw/bnxt_re/qplib_sp.c b/drivers/infiniband/hw/bnxt_re/qplib_sp.c
index 9efd32a3dc55..68981399598d 100644
--- a/drivers/infiniband/hw/bnxt_re/qplib_sp.c
+++ b/drivers/infiniband/hw/bnxt_re/qplib_sp.c
@@ -674,7 +674,7 @@ int bnxt_qplib_reg_mr(struct bnxt_qplib_res *res, struct bnxt_qplib_mrw *mr,
req.log2_pbl_pg_size = cpu_to_le16(((ilog2(PAGE_SIZE) <<
CMDQ_REGISTER_MR_LOG2_PBL_PG_SIZE_SFT) &
CMDQ_REGISTER_MR_LOG2_PBL_PG_SIZE_MASK));
- req.access = (mr->access_flags & 0xFFFF);
+ req.access = (mr->access_flags & BNXT_QPLIB_MR_ACCESS_MASK);
req.va = cpu_to_le64(mr->va);
req.key = cpu_to_le32(mr->lkey);
if (_is_alloc_mr_unified(res->dattr->dev_cap_flags))
diff --git a/drivers/infiniband/hw/bnxt_re/qplib_sp.h b/drivers/infiniband/hw/bnxt_re/qplib_sp.h
index e626b05038a1..09faf4a1e849 100644
--- a/drivers/infiniband/hw/bnxt_re/qplib_sp.h
+++ b/drivers/infiniband/hw/bnxt_re/qplib_sp.h
@@ -111,6 +111,7 @@ struct bnxt_qplib_mrw {
struct bnxt_qplib_pd *pd;
int type;
u32 access_flags;
+#define BNXT_QPLIB_MR_ACCESS_MASK 0xFF
#define BNXT_QPLIB_FR_PMR 0x80000000
u32 lkey;
u32 rkey;
--
2.50.1 (Apple Git-155)

View File

@ -0,0 +1,56 @@
From 57b1289801efb0d9e4c93131706522d79aee7fe3 Mon Sep 17 00:00:00 2001
From: Sreekanth Reddy <sreeredd@redhat.com>
Date: Tue, 19 Aug 2025 13:02:23 -0700
Subject: [PATCH] RDMA/bnxt_re: Fix incorrect display of inactivity_cp in
debugfs output
JIRA: https://issues.redhat.com/browse/RHEL-108694
commit 58d7a965bb2b014d467445d38cdb07099b1f0f77
Author: Gautam R A <gautam-r.a@broadcom.com>
Date: Tue May 20 09:29:07 2025 +0530
RDMA/bnxt_re: Fix incorrect display of inactivity_cp in debugfs output
The inactivity_cp parameter in debugfs was not being read or
written correctly, resulting in "Invalid argument" errors.
Fixed this by ensuring proper mapping of inactivity_cp in
both the map_cc_config_offset_gen0_ext0 and
bnxt_re_fill_gen0_ext0() functions.
Fixes: 656dff55da19 ("RDMA/bnxt_re: Congestion control settings using debugfs hook")
Signed-off-by: Gautam R A <gautam-r.a@broadcom.com>
Link: https://patch.msgid.link/20250520035910.1061918-2-kalesh-anakkur.purayil@broadcom.com
Reviewed-by: Kalesh AP <kalesh-anakkur.purayil@broadcom.com>
Signed-off-by: Leon Romanovsky <leon@kernel.org>
Signed-off-by: Sreekanth Reddy <sreeredd@redhat.com>
diff --git a/drivers/infiniband/hw/bnxt_re/debugfs.c b/drivers/infiniband/hw/bnxt_re/debugfs.c
index af91d16c3c77..a3aad6c3dbec 100644
--- a/drivers/infiniband/hw/bnxt_re/debugfs.c
+++ b/drivers/infiniband/hw/bnxt_re/debugfs.c
@@ -170,6 +170,9 @@ static int map_cc_config_offset_gen0_ext0(u32 offset, struct bnxt_qplib_cc_param
case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_TCP_CP:
*val = ccparam->tcp_cp;
break;
+ case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_INACTIVITY_CP:
+ *val = ccparam->inact_th;
+ break;
default:
return -EINVAL;
}
@@ -247,7 +250,9 @@ static void bnxt_re_fill_gen0_ext0(struct bnxt_qplib_cc_param *ccparam, u32 offs
ccparam->tcp_cp = val;
break;
case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_TX_QUEUE:
+ break;
case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_INACTIVITY_CP:
+ ccparam->inact_th = val;
break;
case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_TIME_PER_PHASE:
ccparam->time_pph = val;
--
2.50.1 (Apple Git-155)

View File

@ -0,0 +1,79 @@
From 5cda728320e19c716ddf48cd704360d164af5775 Mon Sep 17 00:00:00 2001
From: Sreekanth Reddy <sreeredd@redhat.com>
Date: Tue, 19 Aug 2025 14:10:02 -0700
Subject: [PATCH] RDMA/bnxt_re: Fix missing error handling for tx_queue
JIRA: https://issues.redhat.com/browse/RHEL-108694
commit e3d57a00d4d1f36689e9eab80b60d5024361efec
Author: Gautam R A <gautam-r.a@broadcom.com>
Date: Tue May 20 09:29:08 2025 +0530
RDMA/bnxt_re: Fix missing error handling for tx_queue
bnxt_re_fill_gen0_ext0() did not return an error when
attempting to modify CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_TX_QUEUE,
leading to silent failures.
Fixed this by returning -EOPNOTSUPP for tx_queue modifications and
ensuring proper error propagation in bnxt_re_configure_cc().
Fixes: 656dff55da19 ("RDMA/bnxt_re: Congestion control settings using debugfs hook")
Signed-off-by: Gautam R A <gautam-r.a@broadcom.com>
Link: https://patch.msgid.link/20250520035910.1061918-3-kalesh-anakkur.purayil@broadcom.com
Reviewed-by: Kalesh AP <kalesh-anakkur.purayil@broadcom.com>
Signed-off-by: Leon Romanovsky <leon@kernel.org>
Signed-off-by: Sreekanth Reddy <sreeredd@redhat.com>
diff --git a/drivers/infiniband/hw/bnxt_re/debugfs.c b/drivers/infiniband/hw/bnxt_re/debugfs.c
index a3aad6c3dbec..9f6392155d91 100644
--- a/drivers/infiniband/hw/bnxt_re/debugfs.c
+++ b/drivers/infiniband/hw/bnxt_re/debugfs.c
@@ -206,7 +206,7 @@ static ssize_t bnxt_re_cc_config_get(struct file *filp, char __user *buffer,
return simple_read_from_buffer(buffer, usr_buf_len, ppos, (u8 *)(buf), rc);
}
-static void bnxt_re_fill_gen0_ext0(struct bnxt_qplib_cc_param *ccparam, u32 offset, u32 val)
+static int bnxt_re_fill_gen0_ext0(struct bnxt_qplib_cc_param *ccparam, u32 offset, u32 val)
{
u32 modify_mask;
@@ -250,7 +250,7 @@ static void bnxt_re_fill_gen0_ext0(struct bnxt_qplib_cc_param *ccparam, u32 offs
ccparam->tcp_cp = val;
break;
case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_TX_QUEUE:
- break;
+ return -EOPNOTSUPP;
case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_INACTIVITY_CP:
ccparam->inact_th = val;
break;
@@ -263,18 +263,21 @@ static void bnxt_re_fill_gen0_ext0(struct bnxt_qplib_cc_param *ccparam, u32 offs
}
ccparam->mask = modify_mask;
+ return 0;
}
static int bnxt_re_configure_cc(struct bnxt_re_dev *rdev, u32 gen_ext, u32 offset, u32 val)
{
struct bnxt_qplib_cc_param ccparam = { };
+ int rc;
- /* Supporting only Gen 0 now */
- if (gen_ext == CC_CONFIG_GEN0_EXT0)
- bnxt_re_fill_gen0_ext0(&ccparam, offset, val);
- else
+ if (gen_ext != CC_CONFIG_GEN0_EXT0)
return -EINVAL;
+ rc = bnxt_re_fill_gen0_ext0(&ccparam, offset, val);
+ if (rc)
+ return rc;
+
bnxt_qplib_modify_cc(&rdev->qplib_res, &ccparam);
return 0;
}
--
2.50.1 (Apple Git-155)

View File

@ -0,0 +1,42 @@
From 7e413faf8726503ba29dc3c9985c2a51b4d39c17 Mon Sep 17 00:00:00 2001
From: Sreekanth Reddy <sreeredd@redhat.com>
Date: Tue, 19 Aug 2025 15:24:51 -0700
Subject: [PATCH] RDMA/bnxt_re: Fix return code of bnxt_re_configure_cc
JIRA: https://issues.redhat.com/browse/RHEL-108694
commit 990b5c07f677a0b633b41130a70771337c18343e
Author: Kalesh AP <kalesh-anakkur.purayil@broadcom.com>
Date: Tue May 20 09:29:09 2025 +0530
RDMA/bnxt_re: Fix return code of bnxt_re_configure_cc
Driver currently supports modifying GEN0_EXT0 CC parameters
through debugfs hook.
Fixed to return -EOPNOTSUPP instead of -EINVAL in bnxt_re_configure_cc()
when the user tries to modify any other CC parameters.
Fixes: 656dff55da19 ("RDMA/bnxt_re: Congestion control settings using debugfs hook")
Signed-off-by: Kalesh AP <kalesh-anakkur.purayil@broadcom.com>
Link: https://patch.msgid.link/20250520035910.1061918-4-kalesh-anakkur.purayil@broadcom.com
Signed-off-by: Leon Romanovsky <leon@kernel.org>
Signed-off-by: Sreekanth Reddy <sreeredd@redhat.com>
diff --git a/drivers/infiniband/hw/bnxt_re/debugfs.c b/drivers/infiniband/hw/bnxt_re/debugfs.c
index 9f6392155d91..e632f1661b92 100644
--- a/drivers/infiniband/hw/bnxt_re/debugfs.c
+++ b/drivers/infiniband/hw/bnxt_re/debugfs.c
@@ -272,7 +272,7 @@ static int bnxt_re_configure_cc(struct bnxt_re_dev *rdev, u32 gen_ext, u32 offse
int rc;
if (gen_ext != CC_CONFIG_GEN0_EXT0)
- return -EINVAL;
+ return -EOPNOTSUPP;
rc = bnxt_re_fill_gen0_ext0(&ccparam, offset, val);
if (rc)
--
2.50.1 (Apple Git-155)

View File

@ -0,0 +1,93 @@
From 158c90165846bc756b86c514a97a233dc40b6724 Mon Sep 17 00:00:00 2001
From: Sreekanth Reddy <sreeredd@redhat.com>
Date: Tue, 19 Aug 2025 14:11:52 -0700
Subject: [PATCH] RDMA/bnxt_re: convert timeouts to secs_to_jiffies()
JIRA: https://issues.redhat.com/browse/RHEL-108694
commit f873136416293b786e7611d36226c9f5a8f6d20b
Author: Easwar Hariharan <eahariha@linux.microsoft.com>
Date: Tue Feb 25 20:17:30 2025 +0000
RDMA/bnxt_re: convert timeouts to secs_to_jiffies()
Commit b35108a51cf7 ("jiffies: Define secs_to_jiffies()") introduced
secs_to_jiffies(). As the value here is a multiple of 1000, use
secs_to_jiffies() instead of msecs_to_jiffies() to avoid the
multiplication
This is converted using scripts/coccinelle/misc/secs_to_jiffies.cocci with
the following Coccinelle rules:
@depends on patch@
expression E;
@@
-msecs_to_jiffies
+secs_to_jiffies
(E
- * \( 1000 \| MSEC_PER_SEC \)
)
Link: https://lkml.kernel.org/r/20250225-converge-secs-to-jiffies-part-two-v3-16-a43967e36c88@linux.microsoft.com
Signed-off-by: Easwar Hariharan <eahariha@linux.microsoft.com>
Cc: Carlos Maiolino <cem@kernel.org>
Cc: Carlos Maiolino <cmaiolino@redhat.com>
Cc: Chris Mason <clm@fb.com>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Damien Le Maol <dlemoal@kernel.org>
Cc: "Darrick J. Wong" <djwong@kernel.org>
Cc: David Sterba <dsterba@suse.com>
Cc: Dick Kennedy <dick.kennedy@broadcom.com>
Cc: Dongsheng Yang <dongsheng.yang@easystack.cn>
Cc: Fabio Estevam <festevam@gmail.com>
Cc: Frank Li <frank.li@nxp.com>
Cc: Hans de Goede <hdegoede@redhat.com>
Cc: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
Cc: Ilpo Jarvinen <ilpo.jarvinen@linux.intel.com>
Cc: Ilya Dryomov <idryomov@gmail.com>
Cc: James Bottomley <james.bottomley@HansenPartnership.com>
Cc: James Smart <james.smart@broadcom.com>
Cc: Jaroslav Kysela <perex@perex.cz>
Cc: Jason Gunthorpe <jgg@ziepe.ca>
Cc: Jens Axboe <axboe@kernel.dk>
Cc: Josef Bacik <josef@toxicpanda.com>
Cc: Julia Lawall <julia.lawall@inria.fr>
Cc: Kalesh Anakkur Purayil <kalesh-anakkur.purayil@broadcom.com>
Cc: Keith Busch <kbusch@kernel.org>
Cc: Leon Romanovsky <leon@kernel.org>
Cc: Marc Kleine-Budde <mkl@pengutronix.de>
Cc: Mark Brown <broonie@kernel.org>
Cc: "Martin K. Petersen" <martin.petersen@oracle.com>
Cc: Nicolas Palix <nicolas.palix@imag.fr>
Cc: Niklas Cassel <cassel@kernel.org>
Cc: Oded Gabbay <ogabbay@kernel.org>
Cc: Sagi Grimberg <sagi@grimberg.me>
Cc: Sascha Hauer <s.hauer@pengutronix.de>
Cc: Sebastian Reichel <sre@kernel.org>
Cc: Selvin Thyparampil Xavier <selvin.xavier@broadcom.com>
Cc: Shawn Guo <shawnguo@kernel.org>
Cc: Shyam-sundar S-k <Shyam-sundar.S-k@amd.com>
Cc: Takashi Iwai <tiwai@suse.com>
Cc: Takashi Iwai <tiwai@suse.de>
Cc: Xiubo Li <xiubli@redhat.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Sreekanth Reddy <sreeredd@redhat.com>
diff --git a/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c b/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c
index d23074383428..804bc773b4ef 100644
--- a/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c
+++ b/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c
@@ -160,7 +160,7 @@ static int __wait_for_resp(struct bnxt_qplib_rcfw *rcfw, u16 cookie)
wait_event_timeout(cmdq->waitq,
!crsqe->is_in_used ||
test_bit(ERR_DEVICE_DETACHED, &cmdq->flags),
- msecs_to_jiffies(rcfw->max_timeout * 1000));
+ secs_to_jiffies(rcfw->max_timeout));
if (!crsqe->is_in_used)
return 0;
--
2.50.1 (Apple Git-155)

View File

@ -0,0 +1,133 @@
From 0a6054968d4fb03613bfa5655cd560f7faca9110 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Toke=20H=C3=B8iland-J=C3=B8rgensen?= <toke@redhat.com>
Date: Fri, 20 Mar 2026 15:01:50 +0100
Subject: [PATCH] net: openvswitch: Avoid releasing netdev before teardown
completes
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
JIRA: https://redhat.atlassian.net/browse/RHEL-155383
commit 7c770dadfda5cbbde6aa3c4363ed513f1d212bf8
Author: Toke Høiland-Jørgensen <toke@redhat.com>
Date: Wed Mar 18 16:55:51 2026 +0100
net: openvswitch: Avoid releasing netdev before teardown completes
The patch cited in the Fixes tag below changed the teardown code for
OVS ports to no longer unconditionally take the RTNL. After this change,
the netdev_destroy() callback can proceed immediately to the call_rcu()
invocation if the IFF_OVS_DATAPATH flag is already cleared on the
netdev.
The ovs_netdev_detach_dev() function clears the flag before completing
the unregistration, and if it gets preempted after clearing the flag (as
can happen on an -rt kernel), netdev_destroy() can complete and the
device can be freed before the unregistration completes. This leads to a
splat like:
[ 998.393867] Oops: general protection fault, probably for non-canonical address 0xff00000001000239: 0000 [#1] SMP PTI
[ 998.393877] CPU: 42 UID: 0 PID: 55177 Comm: ip Kdump: loaded Not tainted 6.12.0-211.1.1.el10_2.x86_64+rt #1 PREEMPT_RT
[ 998.393886] Hardware name: Dell Inc. PowerEdge R740/0JMK61, BIOS 2.24.0 03/27/2025
[ 998.393889] RIP: 0010:dev_set_promiscuity+0x8d/0xa0
[ 998.393901] Code: 00 00 75 d8 48 8b 53 08 48 83 ba b0 02 00 00 00 75 ca 48 83 c4 08 5b c3 cc cc cc cc 48 83 bf 48 09 00 00 00 75 91 48 8b 47 08 <48> 83 b8 b0 02 00 00 00 74 97 eb 81 0f 1f 80 00 00 00 00 90 90 90
[ 998.393906] RSP: 0018:ffffce5864a5f6a0 EFLAGS: 00010246
[ 998.393912] RAX: ff00000000ffff89 RBX: ffff894d0adf5a05 RCX: 0000000000000000
[ 998.393917] RDX: 0000000000000000 RSI: 00000000ffffffff RDI: ffff894d0adf5a05
[ 998.393921] RBP: ffff894d19252000 R08: ffff894d19252000 R09: 0000000000000000
[ 998.393924] R10: ffff894d19252000 R11: ffff894d192521b8 R12: 0000000000000006
[ 998.393927] R13: ffffce5864a5f738 R14: 00000000ffffffe2 R15: 0000000000000000
[ 998.393931] FS: 00007fad61971800(0000) GS:ffff894cc0140000(0000) knlGS:0000000000000000
[ 998.393936] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 998.393940] CR2: 000055df0a2a6e40 CR3: 000000011c7fe003 CR4: 00000000007726f0
[ 998.393944] PKRU: 55555554
[ 998.393946] Call Trace:
[ 998.393949] <TASK>
[ 998.393952] ? show_trace_log_lvl+0x1b0/0x2f0
[ 998.393961] ? show_trace_log_lvl+0x1b0/0x2f0
[ 998.393975] ? dp_device_event+0x41/0x80 [openvswitch]
[ 998.394009] ? __die_body.cold+0x8/0x12
[ 998.394016] ? die_addr+0x3c/0x60
[ 998.394027] ? exc_general_protection+0x16d/0x390
[ 998.394042] ? asm_exc_general_protection+0x26/0x30
[ 998.394058] ? dev_set_promiscuity+0x8d/0xa0
[ 998.394066] ? ovs_netdev_detach_dev+0x3a/0x80 [openvswitch]
[ 998.394092] dp_device_event+0x41/0x80 [openvswitch]
[ 998.394102] notifier_call_chain+0x5a/0xd0
[ 998.394106] unregister_netdevice_many_notify+0x51b/0xa60
[ 998.394110] rtnl_dellink+0x169/0x3e0
[ 998.394121] ? rt_mutex_slowlock.constprop.0+0x95/0xd0
[ 998.394125] rtnetlink_rcv_msg+0x142/0x3f0
[ 998.394128] ? avc_has_perm_noaudit+0x69/0xf0
[ 998.394130] ? __pfx_rtnetlink_rcv_msg+0x10/0x10
[ 998.394132] netlink_rcv_skb+0x50/0x100
[ 998.394138] netlink_unicast+0x292/0x3f0
[ 998.394141] netlink_sendmsg+0x21b/0x470
[ 998.394145] ____sys_sendmsg+0x39d/0x3d0
[ 998.394149] ___sys_sendmsg+0x9a/0xe0
[ 998.394156] __sys_sendmsg+0x7a/0xd0
[ 998.394160] do_syscall_64+0x7f/0x170
[ 998.394162] entry_SYSCALL_64_after_hwframe+0x76/0x7e
[ 998.394165] RIP: 0033:0x7fad61bf4724
[ 998.394188] Code: 89 02 b8 ff ff ff ff eb bb 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 00 f3 0f 1e fa 80 3d c5 e9 0c 00 00 74 13 b8 2e 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 54 c3 0f 1f 00 48 83 ec 28 89 54 24 1c 48 89
[ 998.394189] RSP: 002b:00007ffd7e2f7cb8 EFLAGS: 00000202 ORIG_RAX: 000000000000002e
[ 998.394191] RAX: ffffffffffffffda RBX: 0000000000000001 RCX: 00007fad61bf4724
[ 998.394193] RDX: 0000000000000000 RSI: 00007ffd7e2f7d20 RDI: 0000000000000003
[ 998.394194] RBP: 00007ffd7e2f7d90 R08: 0000000000000010 R09: 000000000000003f
[ 998.394195] R10: 000055df11558010 R11: 0000000000000202 R12: 00007ffd7e2f8380
[ 998.394196] R13: 0000000069b233d7 R14: 000055df0a256040 R15: 0000000000000000
[ 998.394200] </TASK>
To fix this, reorder the operations in ovs_netdev_detach_dev() to only
clear the flag after completing the other operations, and introduce an
smp_wmb() to make the ordering requirement explicit. The smp_wmb() is
paired with a full smp_mb() in netdev_destroy() to make sure the
call_rcu() invocation does not happen before the unregister operations
are visible.
Reported-by: Minxi Hou <mhou@redhat.com>
Tested-by: Minxi Hou <mhou@redhat.com>
Fixes: 549822767630 ("net: openvswitch: Avoid needlessly taking the RTNL on vport destroy")
Signed-off-by: Toke Høiland-Jørgensen <toke@redhat.com>
Link: https://patch.msgid.link/20260318155554.1133405-1-toke@redhat.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
(cherry picked from commit 7c770dadfda5cbbde6aa3c4363ed513f1d212bf8)
Assisted-by: Patchpal
Signed-off-by: Toke Høiland-Jørgensen <toke@redhat.com>
diff --git a/net/openvswitch/vport-netdev.c b/net/openvswitch/vport-netdev.c
index 6574f9bcdc02..c688dee96503 100644
--- a/net/openvswitch/vport-netdev.c
+++ b/net/openvswitch/vport-netdev.c
@@ -151,11 +151,15 @@ static void vport_netdev_free(struct rcu_head *rcu)
void ovs_netdev_detach_dev(struct vport *vport)
{
ASSERT_RTNL();
- vport->dev->priv_flags &= ~IFF_OVS_DATAPATH;
netdev_rx_handler_unregister(vport->dev);
netdev_upper_dev_unlink(vport->dev,
netdev_master_upper_dev_get(vport->dev));
dev_set_promiscuity(vport->dev, -1);
+
+ /* paired with smp_mb() in netdev_destroy() */
+ smp_wmb();
+
+ vport->dev->priv_flags &= ~IFF_OVS_DATAPATH;
}
static void netdev_destroy(struct vport *vport)
@@ -174,6 +178,9 @@ static void netdev_destroy(struct vport *vport)
rtnl_unlock();
}
+ /* paired with smp_wmb() in ovs_netdev_detach_dev() */
+ smp_mb();
+
call_rcu(&vport->rcu, vport_netdev_free);
}
--
2.50.1 (Apple Git-155)

View File

@ -0,0 +1,63 @@
From e324506b98bf6935e6df4813b989d6a9b333109c Mon Sep 17 00:00:00 2001
From: Mohammad Heib <mheib@redhat.com>
Date: Tue, 17 Mar 2026 19:08:06 +0200
Subject: [PATCH] ionic: fix persistent MAC address override on PF
[ Upstream commit cbcb3cfcdc436d6f91a3d95ecfa9c831abe14aed ]
The use of IONIC_CMD_LIF_SETATTR in the MAC address update path causes
the ionic firmware to update the LIF's identity in its persistent state.
Since the firmware state is maintained across host warm boots and driver
reloads, any MAC change on the Physical Function (PF) becomes "sticky.
This is problematic because it causes ethtool -P to report the
user-configured MAC as the permanent factory address, which breaks
system management tools that rely on a stable hardware identity.
While Virtual Functions (VFs) need this hardware-level programming to
properly handle MAC assignments in guest environments, the PF should
maintain standard transient behavior. This patch gates the
ionic_program_mac call using is_virtfn so that PF MAC changes remain
local to the netdev filters and do not overwrite the firmware's
permanent identity block.
Fixes: 19058be7c48c ("ionic: VF initial random MAC address if no assigned mac")
Signed-off-by: Mohammad Heib <mheib@redhat.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Reviewed-by: Brett Creeley <brett.creeley@amd.com>
Link: https://patch.msgid.link/20260317170806.35390-1-mheib@redhat.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
diff --git a/drivers/net/ethernet/pensando/ionic/ionic_lif.c b/drivers/net/ethernet/pensando/ionic/ionic_lif.c
index d6bea7152805..8119281b26d0 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_lif.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_lif.c
@@ -1718,13 +1718,18 @@ static int ionic_set_mac_address(struct net_device *netdev, void *sa)
if (ether_addr_equal(netdev->dev_addr, mac))
return 0;
- err = ionic_program_mac(lif, mac);
- if (err < 0)
- return err;
+ /* Only program macs for virtual functions to avoid losing the permanent
+ * Mac across warm reset/reboot.
+ */
+ if (lif->ionic->pdev->is_virtfn) {
+ err = ionic_program_mac(lif, mac);
+ if (err < 0)
+ return err;
- if (err > 0)
- netdev_dbg(netdev, "%s: SET and GET ATTR Mac are not equal-due to old FW running\n",
- __func__);
+ if (err > 0)
+ netdev_dbg(netdev, "%s: SET and GET ATTR Mac are not equal-due to old FW running\n",
+ __func__);
+ }
err = eth_prepare_mac_addr_change(netdev, addr);
if (err)
--
2.50.1 (Apple Git-155)

View File

@ -0,0 +1,50 @@
From 266f721e430bee90651dbb9be46ba6ff070c0228 Mon Sep 17 00:00:00 2001
From: Vinay Mulugund <vmulugun@redhat.com>
Date: Wed, 11 Mar 2026 12:27:30 +0530
Subject: [PATCH] net: hv_netvsc: reject RSS hash key programming without RX
indirection table
JIRA: https://issues.redhat.com/browse/RHEL-145154
commit d23564955811da493f34412d7de60fa268c8cb50
Author: Aditya Garg <gargaditya@linux.microsoft.com>
Date: Mon Jan 12 02:01:33 2026 -0800
net: hv_netvsc: reject RSS hash key programming without RX indirection table
RSS configuration requires a valid RX indirection table. When the device
reports a single receive queue, rndis_filter_device_add() does not
allocate an indirection table, accepting RSS hash key updates in this
state leads to a hang.
Fix this by gating netvsc_set_rxfh() on ndc->rx_table_sz and return
-EOPNOTSUPP when the table is absent. This aligns set_rxfh with the device
capabilities and prevents incorrect behavior.
Fixes: 962f3fee83a4 ("netvsc: add ethtool ops to get/set RSS key")
Signed-off-by: Aditya Garg <gargaditya@linux.microsoft.com>
Reviewed-by: Dipayaan Roy <dipayanroy@linux.microsoft.com>
Reviewed-by: Haiyang Zhang <haiyangz@microsoft.com>
Link: https://patch.msgid.link/1768212093-1594-1-git-send-email-gargaditya@linux.microsoft.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
(cherry picked from commit d23564955811da493f34412d7de60fa268c8cb50)
Signed-off-by: Vinay Mulugund <vmulugun@redhat.com>
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
index 313d258a346e..c4243ee74654 100644
--- a/drivers/net/hyperv/netvsc_drv.c
+++ b/drivers/net/hyperv/netvsc_drv.c
@@ -1757,6 +1757,9 @@ static int netvsc_set_rxfh(struct net_device *dev,
rxfh->hfunc != ETH_RSS_HASH_TOP)
return -EOPNOTSUPP;
+ if (!ndc->rx_table_sz)
+ return -EOPNOTSUPP;
+
rndis_dev = ndev->extension;
if (rxfh->indir) {
for (i = 0; i < ndc->rx_table_sz; i++)
--
2.50.1 (Apple Git-155)

View File

@ -0,0 +1,54 @@
From bf9a43aa596c70d0c9c32fa654c39926f1c2ef82 Mon Sep 17 00:00:00 2001
From: CKI Backport Bot <cki-ci-bot+cki-gitlab-backport-bot@redhat.com>
Date: Thu, 26 Mar 2026 17:41:01 +0000
Subject: [PATCH] scsi: qla2xxx: Fix improper freeing of purex item
JIRA: https://redhat.atlassian.net/browse/RHEL-161120
CVE: CVE-2025-68741
commit 78b1a242fe612a755f2158fd206ee6bb577d18ca
Author: Zilin Guan <zilin@seu.edu.cn>
Date: Thu Nov 13 15:12:46 2025 +0000
scsi: qla2xxx: Fix improper freeing of purex item
In qla2xxx_process_purls_iocb(), an item is allocated via
qla27xx_copy_multiple_pkt(), which internally calls
qla24xx_alloc_purex_item().
The qla24xx_alloc_purex_item() function may return a pre-allocated item
from a per-adapter pool for small allocations, instead of dynamically
allocating memory with kzalloc().
An error handling path in qla2xxx_process_purls_iocb() incorrectly uses
kfree() to release the item. If the item was from the pre-allocated
pool, calling kfree() on it is a bug that can lead to memory corruption.
Fix this by using the correct deallocation function,
qla24xx_free_purex_item(), which properly handles both dynamically
allocated and pre-allocated items.
Fixes: 875386b98857 ("scsi: qla2xxx: Add Unsolicited LS Request and Response Support for NVMe")
Signed-off-by: Zilin Guan <zilin@seu.edu.cn>
Reviewed-by: Himanshu Madhani <hmadhani2024@gmail.com>
Link: https://patch.msgid.link/20251113151246.762510-1-zilin@seu.edu.cn
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: CKI Backport Bot <cki-ci-bot+cki-gitlab-backport-bot@redhat.com>
diff --git a/drivers/scsi/qla2xxx/qla_nvme.c b/drivers/scsi/qla2xxx/qla_nvme.c
index 8ee2e337c9e1..6ecf3da765aa 100644
--- a/drivers/scsi/qla2xxx/qla_nvme.c
+++ b/drivers/scsi/qla2xxx/qla_nvme.c
@@ -1292,7 +1292,7 @@ void qla2xxx_process_purls_iocb(void **pkt, struct rsp_que **rsp)
a.reason = FCNVME_RJT_RC_LOGIC;
a.explanation = FCNVME_RJT_EXP_NONE;
xmt_reject = true;
- kfree(item);
+ qla24xx_free_purex_item(item);
goto out;
}
--
2.50.1 (Apple Git-155)

View File

@ -0,0 +1,74 @@
From 30367bfca94e52eeb59b216f5d8d22054aa4f1a8 Mon Sep 17 00:00:00 2001
From: Paulo Alcantara <paalcant@redhat.com>
Date: Tue, 24 Mar 2026 10:39:08 -0300
Subject: [PATCH] smb: client: fix krb5 mount with username option
JIRA: https://issues.redhat.com/browse/RHEL-158991
commit 12b4c5d98cd7ca46d5035a57bcd995df614c14e1
Author: Paulo Alcantara <pc@manguebit.org>
Date: Fri Mar 13 00:03:38 2026 -0300
smb: client: fix krb5 mount with username option
Customer reported that some of their krb5 mounts were failing against
a single server as the client was trying to mount the shares with
wrong credentials. It turned out the client was reusing SMB session
from first mount to try mounting the other shares, even though a
different username= option had been specified to the other mounts.
By using username mount option along with sec=krb5 to search for
principals from keytab is supported by cifs.upcall(8) since
cifs-utils-4.8. So fix this by matching username mount option in
match_session() even with Kerberos.
For example, the second mount below should fail with -ENOKEY as there
is no 'foobar' principal in keytab (/etc/krb5.keytab). The client
ends up reusing SMB session from first mount to perform the second
one, which is wrong.
```
$ ktutil
ktutil: add_entry -password -p testuser -k 1 -e aes256-cts
Password for testuser@ZELDA.TEST:
ktutil: write_kt /etc/krb5.keytab
ktutil: quit
$ klist -ke
Keytab name: FILE:/etc/krb5.keytab
KVNO Principal
---- ----------------------------------------------------------------
1 testuser@ZELDA.TEST (aes256-cts-hmac-sha1-96)
$ mount.cifs //w22-root2/scratch /mnt/1 -o sec=krb5,username=testuser
$ mount.cifs //w22-root2/scratch /mnt/2 -o sec=krb5,username=foobar
$ mount -t cifs | grep -Po 'username=\K\w+'
testuser
testuser
```
Reported-by: Oscar Santos <ossantos@redhat.com>
Signed-off-by: Paulo Alcantara (Red Hat) <pc@manguebit.org>
Cc: David Howells <dhowells@redhat.com>
Cc: linux-cifs@vger.kernel.org
Cc: stable@vger.kernel.org
Signed-off-by: Steve French <stfrench@microsoft.com>
Signed-off-by: Paulo Alcantara <paalcant@redhat.com>
diff --git a/fs/smb/client/connect.c b/fs/smb/client/connect.c
index a0b45710bd04..37ad111331b3 100644
--- a/fs/smb/client/connect.c
+++ b/fs/smb/client/connect.c
@@ -1952,6 +1952,10 @@ static int match_session(struct cifs_ses *ses,
case Kerberos:
if (!uid_eq(ctx->cred_uid, ses->cred_uid))
return 0;
+ if (strncmp(ses->user_name ?: "",
+ ctx->username ?: "",
+ CIFS_MAX_USERNAME_LEN))
+ return 0;
break;
case NTLMv2:
case RawNTLMSSP:
--
2.50.1 (Apple Git-155)

View File

@ -0,0 +1,66 @@
From 2b6abddbbd260c6ed60125a41e9aa32cf3e31296 Mon Sep 17 00:00:00 2001
From: CKI Backport Bot <cki-ci-bot+cki-gitlab-backport-bot@redhat.com>
Date: Wed, 25 Feb 2026 14:34:51 +0000
Subject: [PATCH] ALSA: hda/tas2781: Ignore reset check for SPI device
JIRA: https://issues.redhat.com/browse/RHEL-148197
commit 908ef80e31e4d3bd953a0088fe57640cd9ae7b3e
Author: Baojun Xu <baojun.xu@ti.com>
Date: Wed Feb 11 11:09:46 2026 +0800
ALSA: hda/tas2781: Ignore reset check for SPI device
In the SPI driver probe, the device should be in the default state, so the
device status check is not necessary. It should be forced to do the
firmware download as I2C device.
Signed-off-by: Baojun Xu <baojun.xu@ti.com>
Link: https://patch.msgid.link/20260211030946.2330-1-baojun.xu@ti.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: CKI Backport Bot <cki-ci-bot+cki-gitlab-backport-bot@redhat.com>
diff --git a/sound/hda/codecs/side-codecs/tas2781_hda_spi.c b/sound/hda/codecs/side-codecs/tas2781_hda_spi.c
index b9a55672bf15..488e35dac952 100644
--- a/sound/hda/codecs/side-codecs/tas2781_hda_spi.c
+++ b/sound/hda/codecs/side-codecs/tas2781_hda_spi.c
@@ -634,7 +634,7 @@ static void tasdev_fw_ready(const struct firmware *fmw, void *context)
struct tasdevice_priv *tas_priv = context;
struct tas2781_hda *tas_hda = dev_get_drvdata(tas_priv->dev);
struct hda_codec *codec = tas_priv->codec;
- int ret, val;
+ int ret;
pm_runtime_get_sync(tas_priv->dev);
guard(mutex)(&tas_priv->codec_lock);
@@ -673,20 +673,14 @@ static void tasdev_fw_ready(const struct firmware *fmw, void *context)
tas_priv->rcabin.profile_cfg_id = 0;
tas_priv->fw_state = TASDEVICE_DSP_FW_ALL_OK;
- ret = tasdevice_spi_dev_read(tas_priv, tas_priv->index,
- TAS2781_REG_CLK_CONFIG, &val);
- if (ret < 0)
- goto out;
- if (val == TAS2781_REG_CLK_CONFIG_RESET) {
- ret = tasdevice_prmg_load(tas_priv, 0);
- if (ret < 0) {
- dev_err(tas_priv->dev, "FW download failed = %d\n",
- ret);
- goto out;
- }
- tas_priv->fw_state = TASDEVICE_DSP_FW_ALL_OK;
+ ret = tasdevice_prmg_load(tas_priv, 0);
+ if (ret < 0) {
+ dev_err(tas_priv->dev, "FW download failed = %d\n", ret);
+ goto out;
}
+ tas_priv->fw_state = TASDEVICE_DSP_FW_ALL_OK;
+
if (tas_priv->fmw->nr_programs > 0)
tas_priv->tasdevice[tas_priv->index].cur_prog = 0;
if (tas_priv->fmw->nr_configurations > 0)
--
2.50.1 (Apple Git-155)

View File

@ -0,0 +1,64 @@
From 4270afcc8324648b92a33e5450e4d6bc9bf925d9 Mon Sep 17 00:00:00 2001
From: Mohammad Heib <mheib@redhat.com>
Date: Mon, 9 Feb 2026 10:10:58 +0200
Subject: [PATCH] i40e: drop udp_tunnel_get_rx_info() call from i40e_open()
JIRA: https://issues.redhat.com/browse/RHEL-143670
commit 40857194956dcaf3d2b66d6bd113d844c93bef54
Author: Mohammad Heib <mheib@redhat.com>
Date: Sun Dec 28 21:40:20 2025 +0200
i40e: drop udp_tunnel_get_rx_info() call from i40e_open()
The i40e driver calls udp_tunnel_get_rx_info() during i40e_open().
This is redundant because UDP tunnel RX offload state is preserved
across device down/up cycles. The udp_tunnel core handles
synchronization automatically when required.
Furthermore, recent changes in the udp_tunnel infrastructure require
querying RX info while holding the udp_tunnel lock. Calling it
directly from the ndo_open path violates this requirement,
triggering the following lockdep warning:
Call Trace:
<TASK>
? __udp_tunnel_nic_assert_locked+0x39/0x40 [udp_tunnel]
i40e_open+0x135/0x14f [i40e]
__dev_open+0x121/0x2e0
__dev_change_flags+0x227/0x270
dev_change_flags+0x3d/0xb0
devinet_ioctl+0x56f/0x860
sock_do_ioctl+0x7b/0x130
__x64_sys_ioctl+0x91/0xd0
do_syscall_64+0x90/0x170
...
</TASK>
Remove the redundant and unsafe call to udp_tunnel_get_rx_info() from
i40e_open() resolve the locking violation.
Fixes: 1ead7501094c ("udp_tunnel: remove rtnl_lock dependency")
Signed-off-by: Mohammad Heib <mheib@redhat.com>
Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
Reviewed-by: Paul Menzel <pmenzel@molgen.mpg.de>
Tested-by: Rinitha S <sx.rinitha@intel.com> (A Contingent worker at Intel)
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
Signed-off-by: Mohammad Heib <mheib@redhat.com>
diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c
index f418eef4323b..92df70499b6e 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_main.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
@@ -9054,7 +9054,6 @@ int i40e_open(struct net_device *netdev)
TCP_FLAG_FIN |
TCP_FLAG_CWR) >> 16);
wr32(&pf->hw, I40E_GLLAN_TSOMSK_L, be32_to_cpu(TCP_FLAG_CWR) >> 16);
- udp_tunnel_get_rx_info(netdev);
return 0;
}
--
2.50.1 (Apple Git-155)

View File

@ -0,0 +1,65 @@
From 6c8fced68178676061687969c26e1e61b3c91ecd Mon Sep 17 00:00:00 2001
From: Mohammad Heib <mheib@redhat.com>
Date: Mon, 9 Feb 2026 10:10:58 +0200
Subject: [PATCH] ice: drop udp_tunnel_get_rx_info() call from ndo_open()
JIRA: https://issues.redhat.com/browse/RHEL-143670
commit 234e615bfece9e3e91c50fe49ab9e68ee37c791a
Author: Mohammad Heib <mheib@redhat.com>
Date: Sun Dec 28 21:40:21 2025 +0200
ice: drop udp_tunnel_get_rx_info() call from ndo_open()
The ice driver calls udp_tunnel_get_rx_info() during ice_open_internal().
This is redundant because UDP tunnel RX offload state is preserved
across device down/up cycles. The udp_tunnel core handles
synchronization automatically when required.
Furthermore, recent changes in the udp_tunnel infrastructure require
querying RX info while holding the udp_tunnel lock. Calling it
directly from the ndo_open path violates this requirement,
triggering the following lockdep warning:
Call Trace:
<TASK>
ice_open_internal+0x253/0x350 [ice]
__udp_tunnel_nic_assert_locked+0x86/0xb0 [udp_tunnel]
__dev_open+0x2f5/0x880
__dev_change_flags+0x44c/0x660
netif_change_flags+0x80/0x160
devinet_ioctl+0xd21/0x15f0
inet_ioctl+0x311/0x350
sock_ioctl+0x114/0x220
__x64_sys_ioctl+0x131/0x1a0
...
</TASK>
Remove the redundant and unsafe call to udp_tunnel_get_rx_info() from
ice_open_internal() to resolve the locking violation
Fixes: 1ead7501094c ("udp_tunnel: remove rtnl_lock dependency")
Signed-off-by: Mohammad Heib <mheib@redhat.com>
Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
Tested-by: Rinitha S <sx.rinitha@intel.com> (A Contingent worker at Intel)
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
Signed-off-by: Mohammad Heib <mheib@redhat.com>
diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c
index d89ae9e3a168..04f71716a70f 100644
--- a/drivers/net/ethernet/intel/ice/ice_main.c
+++ b/drivers/net/ethernet/intel/ice/ice_main.c
@@ -9624,9 +9624,6 @@ int ice_open_internal(struct net_device *netdev)
netdev_err(netdev, "Failed to open VSI 0x%04X on switch 0x%04X\n",
vsi->vsi_num, vsi->vsw->sw_id);
- /* Update existing tunnels information */
- udp_tunnel_get_rx_info(netdev);
-
return err;
}
--
2.50.1 (Apple Git-155)

View File

@ -0,0 +1,49 @@
From 8ea33562256c638f6864f56a0620b1d998e3ade4 Mon Sep 17 00:00:00 2001
From: Jan Stancek <jstancek@redhat.com>
Date: Mon, 9 Mar 2026 08:47:13 +0100
Subject: [PATCH] x86/boot: Handle relative CONFIG_EFI_SBAT_FILE file paths
JIRA: https://issues.redhat.com/browse/RHEL-132871
Upstream Status: linux.git
commit 3d1973a0c76a78a4728cff13648a188ed486cf44
Author: Jan Stancek <jstancek@redhat.com>
Date: Wed Feb 25 20:30:23 2026 +0100
x86/boot: Handle relative CONFIG_EFI_SBAT_FILE file paths
CONFIG_EFI_SBAT_FILE can be a relative path. When compiling using a different
output directory (O=) the build currently fails because it can't find the
filename set in CONFIG_EFI_SBAT_FILE:
arch/x86/boot/compressed/sbat.S: Assembler messages:
arch/x86/boot/compressed/sbat.S:6: Error: file not found: kernel.sbat
Add $(srctree) as include dir for sbat.o.
[ bp: Massage commit message. ]
Fixes: 61b57d35396a ("x86/efi: Implement support for embedding SBAT data for x86")
Signed-off-by: Jan Stancek <jstancek@redhat.com>
Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
Reviewed-by: Vitaly Kuznetsov <vkuznets@redhat.com>
Cc: <stable@kernel.org>
Link: https://patch.msgid.link/f4eda155b0cef91d4d316b4e92f5771cb0aa7187.1772047658.git.jstancek@redhat.com
Signed-off-by: Jan Stancek <jstancek@redhat.com>
diff --git a/arch/x86/boot/compressed/Makefile b/arch/x86/boot/compressed/Makefile
index c6fa7fa71db4..9f521bff57a4 100644
--- a/arch/x86/boot/compressed/Makefile
+++ b/arch/x86/boot/compressed/Makefile
@@ -111,6 +111,7 @@ vmlinux-objs-$(CONFIG_EFI_SBAT) += $(obj)/sbat.o
ifdef CONFIG_EFI_SBAT
$(obj)/sbat.o: $(CONFIG_EFI_SBAT_FILE)
+AFLAGS_sbat.o += -I $(srctree)
endif
$(obj)/vmlinux: $(vmlinux-objs-y) $(vmlinux-libs-y) FORCE
--
2.50.1 (Apple Git-155)

View File

@ -0,0 +1,100 @@
From a64542a8df51ed10c2d6ac1cbfd20281cadb6e6a Mon Sep 17 00:00:00 2001
From: CKI Backport Bot <cki-ci-bot+cki-gitlab-backport-bot@redhat.com>
Date: Tue, 7 Apr 2026 09:07:40 +0000
Subject: [PATCH] net/sched: Only allow act_ct to bind to clsact/ingress qdiscs
and shared blocks
JIRA: https://redhat.atlassian.net/browse/RHEL-164343
CVE: CVE-2026-23270
commit 11cb63b0d1a0685e0831ae3c77223e002ef18189
Author: Victor Nogueira <victor@mojatatu.com>
Date: Wed Feb 25 10:43:48 2026 -0300
net/sched: Only allow act_ct to bind to clsact/ingress qdiscs and shared blocks
As Paolo said earlier [1]:
"Since the blamed commit below, classify can return TC_ACT_CONSUMED while
the current skb being held by the defragmentation engine. As reported by
GangMin Kim, if such packet is that may cause a UaF when the defrag engine
later on tries to tuch again such packet."
act_ct was never meant to be used in the egress path, however some users
are attaching it to egress today [2]. Attempting to reach a middle
ground, we noticed that, while most qdiscs are not handling
TC_ACT_CONSUMED, clsact/ingress qdiscs are. With that in mind, we
address the issue by only allowing act_ct to bind to clsact/ingress
qdiscs and shared blocks. That way it's still possible to attach act_ct to
egress (albeit only with clsact).
[1] https://lore.kernel.org/netdev/674b8cbfc385c6f37fb29a1de08d8fe5c2b0fbee.1771321118.git.pabeni@redhat.com/
[2] https://lore.kernel.org/netdev/cc6bfb4a-4a2b-42d8-b9ce-7ef6644fb22b@ovn.org/
Reported-by: GangMin Kim <km.kim1503@gmail.com>
Fixes: 3f14b377d01d ("net/sched: act_ct: fix skb leak and crash on ooo frags")
CC: stable@vger.kernel.org
Signed-off-by: Victor Nogueira <victor@mojatatu.com>
Acked-by: Jamal Hadi Salim <jhs@mojatatu.com>
Link: https://patch.msgid.link/20260225134349.1287037-1-victor@mojatatu.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: CKI Backport Bot <cki-ci-bot+cki-gitlab-backport-bot@redhat.com>
diff --git a/include/net/act_api.h b/include/net/act_api.h
index 2894cfff2da3..6b09f4587885 100644
--- a/include/net/act_api.h
+++ b/include/net/act_api.h
@@ -68,6 +68,7 @@ struct tc_action {
#define TCA_ACT_FLAGS_REPLACE (1U << (TCA_ACT_FLAGS_USER_BITS + 2))
#define TCA_ACT_FLAGS_NO_RTNL (1U << (TCA_ACT_FLAGS_USER_BITS + 3))
#define TCA_ACT_FLAGS_AT_INGRESS (1U << (TCA_ACT_FLAGS_USER_BITS + 4))
+#define TCA_ACT_FLAGS_AT_INGRESS_OR_CLSACT (1U << (TCA_ACT_FLAGS_USER_BITS + 5))
/* Update lastuse only if needed, to avoid dirtying a cache line.
* We use a temp variable to avoid fetching jiffies twice.
diff --git a/net/sched/act_ct.c b/net/sched/act_ct.c
index e6ea788da01d..dfae934d26c7 100644
--- a/net/sched/act_ct.c
+++ b/net/sched/act_ct.c
@@ -1358,6 +1358,12 @@ static int tcf_ct_init(struct net *net, struct nlattr *nla,
return -EINVAL;
}
+ if (bind && !(flags & TCA_ACT_FLAGS_AT_INGRESS_OR_CLSACT)) {
+ NL_SET_ERR_MSG_MOD(extack,
+ "Attaching ct to a non ingress/clsact qdisc is unsupported");
+ return -EOPNOTSUPP;
+ }
+
err = nla_parse_nested(tb, TCA_CT_MAX, nla, ct_policy, extack);
if (err < 0)
return err;
diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c
index 5399a46f58dd..0d76e6917155 100644
--- a/net/sched/cls_api.c
+++ b/net/sched/cls_api.c
@@ -2228,6 +2228,11 @@ static bool is_qdisc_ingress(__u32 classid)
return (TC_H_MIN(classid) == TC_H_MIN(TC_H_MIN_INGRESS));
}
+static bool is_ingress_or_clsact(struct tcf_block *block, struct Qdisc *q)
+{
+ return tcf_block_shared(block) || (q && !!(q->flags & TCQ_F_INGRESS));
+}
+
static int tc_new_tfilter(struct sk_buff *skb, struct nlmsghdr *n,
struct netlink_ext_ack *extack)
{
@@ -2420,6 +2425,8 @@ static int tc_new_tfilter(struct sk_buff *skb, struct nlmsghdr *n,
flags |= TCA_ACT_FLAGS_NO_RTNL;
if (is_qdisc_ingress(parent))
flags |= TCA_ACT_FLAGS_AT_INGRESS;
+ if (is_ingress_or_clsact(block, q))
+ flags |= TCA_ACT_FLAGS_AT_INGRESS_OR_CLSACT;
err = tp->ops->change(net, skb, tp, cl, t->tcm_handle, tca, &fh,
flags, extack);
if (err == 0) {
--
2.50.1 (Apple Git-155)

View File

@ -0,0 +1,71 @@
From aa6ff47bec14a3ff3e61d5156611282ea4af0cd5 Mon Sep 17 00:00:00 2001
From: Jaroslav Kysela <jkysela@redhat.com>
Date: Thu, 5 Mar 2026 15:06:49 +0100
Subject: [PATCH] ASoC: SDCA: Tidy up some memory allocations
JIRA: https://issues.redhat.com/browse/RHEL-85741
commit 61d2a7699ab39d448f44919ef15c16187e6f70ec
Author: Charles Keepax <ckeepax@opensource.cirrus.com>
Date: Thu Jan 15 11:46:07 2026 +0000
ASoC: SDCA: Tidy up some memory allocations
It is slightly better to deference the type being allocate for a sizeof
rather than manually using the type. Saves effort if types change in the
future. This results in no functional changes, just tidies up the style
of the code a little.
Signed-off-by: Charles Keepax <ckeepax@opensource.cirrus.com>
Link: https://patch.msgid.link/20260115114607.271990-1-ckeepax@opensource.cirrus.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Jaroslav Kysela <jkysela@redhat.com>
diff --git a/sound/soc/sdca/sdca_fdl.c b/sound/soc/sdca/sdca_fdl.c
index 3180ebd07c40..8bee9f23c473 100644
--- a/sound/soc/sdca/sdca_fdl.c
+++ b/sound/soc/sdca/sdca_fdl.c
@@ -487,7 +487,7 @@ int sdca_fdl_alloc_state(struct sdca_interrupt *interrupt)
struct device *dev = interrupt->dev;
struct fdl_state *fdl_state;
- fdl_state = devm_kzalloc(dev, sizeof(struct fdl_state), GFP_KERNEL);
+ fdl_state = devm_kzalloc(dev, sizeof(*fdl_state), GFP_KERNEL);
if (!fdl_state)
return -ENOMEM;
diff --git a/sound/soc/sdca/sdca_functions.c b/sound/soc/sdca/sdca_functions.c
index acac066f1d8d..80c71116e6d4 100644
--- a/sound/soc/sdca/sdca_functions.c
+++ b/sound/soc/sdca/sdca_functions.c
@@ -952,7 +952,7 @@ static int find_sdca_entity_control(struct device *dev, struct sdca_entity *enti
}
control->values = devm_kcalloc(dev, hweight64(control->cn_list),
- sizeof(int), GFP_KERNEL);
+ sizeof(*control->values), GFP_KERNEL);
if (!control->values)
return -ENOMEM;
@@ -2048,7 +2048,7 @@ static int find_sdca_filesets(struct device *dev, struct sdw_slave *sdw,
fwnode_property_read_u32_array(function_node, "mipi-sdca-file-set-id-list",
filesets_list, num_sets);
- sets = devm_kcalloc(dev, num_sets, sizeof(struct sdca_fdl_set), GFP_KERNEL);
+ sets = devm_kcalloc(dev, num_sets, sizeof(*sets), GFP_KERNEL);
if (!sets)
return -ENOMEM;
@@ -2074,7 +2074,7 @@ static int find_sdca_filesets(struct device *dev, struct sdw_slave *sdw,
dev_dbg(dev, "fileset: %#x\n", filesets_list[i]);
files = devm_kcalloc(dev, num_entries / mult_fileset,
- sizeof(struct sdca_fdl_file), GFP_KERNEL);
+ sizeof(*files), GFP_KERNEL);
if (!files)
return -ENOMEM;
--
2.50.1 (Apple Git-155)

View File

@ -0,0 +1,70 @@
From 1351c2e480a0e7b2c42ac6016c7fdf61de18ee68 Mon Sep 17 00:00:00 2001
From: Jaroslav Kysela <jkysela@redhat.com>
Date: Thu, 5 Mar 2026 15:07:17 +0100
Subject: [PATCH] ASoC: SDCA: Handle CONFIG_PM_SLEEP not being set
JIRA: https://issues.redhat.com/browse/RHEL-85741
commit 7a3d1b04d938f31e112fe09c0ffc1af830ba1f6d
Author: Charles Keepax <ckeepax@opensource.cirrus.com>
Date: Thu Jan 15 14:11:06 2026 +0000
ASoC: SDCA: Handle CONFIG_PM_SLEEP not being set
If CONFIG_PM_SLEEP is not set the completion used will not exist. Update
the code to avoid the build error this introduces, without PM_SLEEP it
should be safe to always run the conditional code.
Fixes: ffd7e8a10111 ("ASoC: SDCA: Device boot into the system suspend process")
Reported-by: kernel test robot <lkp@intel.com>
Closes: https://lore.kernel.org/oe-kbuild-all/202601151803.XY7KryHC-lkp@intel.com/
Signed-off-by: Charles Keepax <ckeepax@opensource.cirrus.com>
Link: https://patch.msgid.link/20260115141107.564929-1-ckeepax@opensource.cirrus.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Jaroslav Kysela <jkysela@redhat.com>
diff --git a/sound/soc/sdca/sdca_interrupts.c b/sound/soc/sdca/sdca_interrupts.c
index cc40732c30cc..d9e22cf40f77 100644
--- a/sound/soc/sdca/sdca_interrupts.c
+++ b/sound/soc/sdca/sdca_interrupts.c
@@ -198,6 +198,18 @@ static irqreturn_t hid_handler(int irq, void *data)
return irqret;
}
+#ifdef CONFIG_PM_SLEEP
+static bool no_pm_in_progress(struct device *dev)
+{
+ return completion_done(&dev->power.completion);
+}
+#else
+static bool no_pm_in_progress(struct device *dev)
+{
+ return true;
+}
+#endif
+
static irqreturn_t fdl_owner_handler(int irq, void *data)
{
struct sdca_interrupt *interrupt = data;
@@ -209,7 +221,7 @@ static irqreturn_t fdl_owner_handler(int irq, void *data)
* FDL has to run from the system resume handler, at which point
* we can't wait for the pm runtime.
*/
- if (completion_done(&dev->power.completion)) {
+ if (no_pm_in_progress(dev)) {
ret = pm_runtime_get_sync(dev);
if (ret < 0) {
dev_err(dev, "failed to resume for fdl: %d\n", ret);
@@ -223,7 +235,7 @@ static irqreturn_t fdl_owner_handler(int irq, void *data)
irqret = IRQ_HANDLED;
error:
- if (completion_done(&dev->power.completion))
+ if (no_pm_in_progress(dev))
pm_runtime_put(dev);
return irqret;
}
--
2.50.1 (Apple Git-155)

View File

@ -0,0 +1,139 @@
From afcc1ec4a47228eb2f8a8f1f79a9dbf3918a9c16 Mon Sep 17 00:00:00 2001
From: Jaroslav Kysela <jkysela@redhat.com>
Date: Thu, 5 Mar 2026 15:04:28 +0100
Subject: [PATCH] ASoC: SDCA: Update counting of SU/GE DAPM routes
JIRA: https://issues.redhat.com/browse/RHEL-85741
commit 1fb720d33eecdb9a90ee340b3000ba378d49f5ca
Author: Charles Keepax <ckeepax@opensource.cirrus.com>
Date: Wed Feb 25 14:01:16 2026 +0000
ASoC: SDCA: Update counting of SU/GE DAPM routes
Device Layer Selector Unit's are controlled by a Group Entity control
rather than by the host directly. For the purposes of the ASoC class
driver the number of input routes to the SU is controlled by the number
of options within the Group Entity Selected Mode Control. ie. One valid
DAPM route for each valid route defined in the Group Entity.
Currently the code assumes that a Device Layer SU will have a number of
routes equal to the number of potential sources for the SU. ie. it
counts the routes using the SU, but then creates the routes using the
GE. However, this isn't actually true, it is perfectly allowed for the
GE to only define options for some of the potential sources of the SU.o
In such a case the number of routes return will not match those created,
leading to either an overflow of the routes array or undefined routes to
be past to the ASoC core, both of which generally lead to the sound card
failing to probe.
Update the handling for the counting of routes to count the connected
routes on the GE itself and then ignore the source routes on the SU.
This makes it match the logic generating the routes and ensuring that
both remain in sync.
Fixes: 2c8b3a8e6aa8 ("ASoC: SDCA: Create DAPM widgets and routes from DisCo")
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.dev>
Signed-off-by: Charles Keepax <ckeepax@opensource.cirrus.com>
Link: https://patch.msgid.link/20260225140118.402695-3-ckeepax@opensource.cirrus.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Jaroslav Kysela <jkysela@redhat.com>
diff --git a/sound/soc/sdca/sdca_asoc.c b/sound/soc/sdca/sdca_asoc.c
index 65e87de1563b..49cbf38b7adb 100644
--- a/sound/soc/sdca/sdca_asoc.c
+++ b/sound/soc/sdca/sdca_asoc.c
@@ -50,6 +50,25 @@ static bool readonly_control(struct sdca_control *control)
return control->has_fixed || control->mode == SDCA_ACCESS_MODE_RO;
}
+static int ge_count_routes(struct sdca_entity *entity)
+{
+ int count = 0;
+ int i, j;
+
+ for (i = 0; i < entity->ge.num_modes; i++) {
+ struct sdca_ge_mode *mode = &entity->ge.modes[i];
+
+ for (j = 0; j < mode->num_controls; j++) {
+ struct sdca_ge_control *affected = &mode->controls[j];
+
+ if (affected->sel != SDCA_CTL_SU_SELECTOR || affected->val)
+ count++;
+ }
+ }
+
+ return count;
+}
+
/**
* sdca_asoc_count_component - count the various component parts
* @dev: Pointer to the device against which allocations will be done.
@@ -73,6 +92,7 @@ int sdca_asoc_count_component(struct device *dev, struct sdca_function_data *fun
int *num_widgets, int *num_routes, int *num_controls,
int *num_dais)
{
+ struct sdca_control *control;
int i, j;
*num_widgets = function->num_entities - 1;
@@ -82,6 +102,7 @@ int sdca_asoc_count_component(struct device *dev, struct sdca_function_data *fun
for (i = 0; i < function->num_entities - 1; i++) {
struct sdca_entity *entity = &function->entities[i];
+ bool skip_primary_routes = false;
/* Add supply/DAI widget connections */
switch (entity->type) {
@@ -95,6 +116,17 @@ int sdca_asoc_count_component(struct device *dev, struct sdca_function_data *fun
case SDCA_ENTITY_TYPE_PDE:
*num_routes += entity->pde.num_managed;
break;
+ case SDCA_ENTITY_TYPE_GE:
+ *num_routes += ge_count_routes(entity);
+ skip_primary_routes = true;
+ break;
+ case SDCA_ENTITY_TYPE_SU:
+ control = sdca_selector_find_control(dev, entity, SDCA_CTL_SU_SELECTOR);
+ if (!control)
+ return -EINVAL;
+
+ skip_primary_routes = (control->layers == SDCA_ACCESS_LAYER_DEVICE);
+ break;
default:
break;
}
@@ -103,7 +135,8 @@ int sdca_asoc_count_component(struct device *dev, struct sdca_function_data *fun
(*num_routes)++;
/* Add primary entity connections from DisCo */
- *num_routes += entity->num_sources;
+ if (!skip_primary_routes)
+ *num_routes += entity->num_sources;
for (j = 0; j < entity->num_controls; j++) {
if (exported_control(entity, &entity->controls[j]))
@@ -406,7 +439,6 @@ static int entity_parse_su_device(struct device *dev,
struct snd_soc_dapm_route **route)
{
struct sdca_control_range *range;
- int num_routes = 0;
int i, j;
if (!entity->group) {
@@ -442,11 +474,6 @@ static int entity_parse_su_device(struct device *dev,
return -EINVAL;
}
- if (++num_routes > entity->num_sources) {
- dev_err(dev, "%s: too many input routes\n", entity->label);
- return -EINVAL;
- }
-
term = sdca_range_search(range, SDCA_SELECTED_MODE_INDEX,
mode->val, SDCA_SELECTED_MODE_TERM_TYPE);
if (!term) {
--
2.50.1 (Apple Git-155)

View File

@ -0,0 +1,65 @@
From 105ead878dbfc6db2beb895ba2bc03d7ad620811 Mon Sep 17 00:00:00 2001
From: Jaroslav Kysela <jkysela@redhat.com>
Date: Thu, 5 Mar 2026 15:05:23 +0100
Subject: [PATCH] ASoC: add snd_soc_lookup_component_by_name helper
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
JIRA: https://issues.redhat.com/browse/RHEL-85741
commit 98eb42c7de6b0185c914df4cca61b49ff76821ee
Author: Bard Liao <yung-chuan.liao@linux.intel.com>
Date: Wed Feb 25 21:50:02 2026 +0800
ASoC: add snd_soc_lookup_component_by_name helper
Add a helper to help user to get the component by name.
Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Reviewed-by: Charles Keepax <ckeepax@opensource.cirrus.com>
Reviewed-by: Péter Ujfalusi <peter.ujfalusi@linux.intel.com>
Link: https://patch.msgid.link/20260225135004.2322987-2-yung-chuan.liao@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Jaroslav Kysela <jkysela@redhat.com>
diff --git a/include/sound/soc.h b/include/sound/soc.h
index f0d837424b4e..753a4a5aecd6 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -465,6 +465,7 @@ struct snd_soc_component *snd_soc_lookup_component_nolocked(struct device *dev,
const char *driver_name);
struct snd_soc_component *snd_soc_lookup_component(struct device *dev,
const char *driver_name);
+struct snd_soc_component *snd_soc_lookup_component_by_name(const char *component_name);
int soc_new_pcm(struct snd_soc_pcm_runtime *rtd);
#ifdef CONFIG_SND_SOC_COMPRESS
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 9dd84d73046b..065fef528f02 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -404,6 +404,19 @@ struct snd_soc_component *snd_soc_lookup_component(struct device *dev,
}
EXPORT_SYMBOL_GPL(snd_soc_lookup_component);
+struct snd_soc_component *snd_soc_lookup_component_by_name(const char *component_name)
+{
+ struct snd_soc_component *component;
+
+ guard(mutex)(&client_mutex);
+ for_each_component(component)
+ if (strstr(component->name, component_name))
+ return component;
+
+ return NULL;
+}
+EXPORT_SYMBOL_GPL(snd_soc_lookup_component_by_name);
+
struct snd_soc_pcm_runtime
*snd_soc_get_pcm_runtime(struct snd_soc_card *card,
struct snd_soc_dai_link *dai_link)
--
2.50.1 (Apple Git-155)

View File

@ -0,0 +1,78 @@
From 97fd7dca352424825024946458c26d8729e2f72b Mon Sep 17 00:00:00 2001
From: Jaroslav Kysela <jkysela@redhat.com>
Date: Thu, 5 Mar 2026 15:05:45 +0100
Subject: [PATCH] ASoC: soc_sdw_utils: partial match the codec name
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
JIRA: https://issues.redhat.com/browse/RHEL-85741
commit c5ae3d8bc968a28aaeefbb772ec42e50cf3a15f0
Author: Bard Liao <yung-chuan.liao@linux.intel.com>
Date: Wed Feb 25 21:50:03 2026 +0800
ASoC: soc_sdw_utils: partial match the codec name
Currently, we can set codec name in the dai info which will be set as
the codec component name in a DAI link. However, the codec name may
not be fixed. For example, there is an index in a SDCA codec name and
that is not fixed. Lookup the fixed codec name string from the component
list to get the right component name to ensure the DAI link will bind
to the right codec component.
Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Reviewed-by: Charles Keepax <ckeepax@opensource.cirrus.com>
Reviewed-by: Péter Ujfalusi <peter.ujfalusi@linux.intel.com>
Link: https://patch.msgid.link/20260225135004.2322987-3-yung-chuan.liao@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Jaroslav Kysela <jkysela@redhat.com>
diff --git a/sound/soc/sdw_utils/soc_sdw_utils.c b/sound/soc/sdw_utils/soc_sdw_utils.c
index 2f3c9698a0e8..88afb14e1ed3 100644
--- a/sound/soc/sdw_utils/soc_sdw_utils.c
+++ b/sound/soc/sdw_utils/soc_sdw_utils.c
@@ -1213,8 +1213,18 @@ const char *asoc_sdw_get_codec_name(struct device *dev,
const struct snd_soc_acpi_link_adr *adr_link,
int adr_index)
{
- if (dai_info->codec_name)
- return devm_kstrdup(dev, dai_info->codec_name, GFP_KERNEL);
+ if (dai_info->codec_name) {
+ struct snd_soc_component *component;
+
+ component = snd_soc_lookup_component_by_name(dai_info->codec_name);
+ if (component) {
+ dev_dbg(dev, "%s found component %s for codec_name %s\n",
+ __func__, component->name, dai_info->codec_name);
+ return devm_kstrdup(dev, component->name, GFP_KERNEL);
+ } else {
+ return devm_kstrdup(dev, dai_info->codec_name, GFP_KERNEL);
+ }
+ }
return _asoc_sdw_get_codec_name(dev, adr_link, adr_index);
}
@@ -1526,7 +1536,17 @@ int asoc_sdw_parse_sdw_endpoints(struct snd_soc_card *card,
return -EINVAL;
for (j = 0; j < codec_info->aux_num; j++) {
- soc_aux->dlc.name = codec_info->auxs[j].codec_name;
+ struct snd_soc_component *component;
+
+ component = snd_soc_lookup_component_by_name(codec_info->auxs[j].codec_name);
+ if (component) {
+ dev_dbg(dev, "%s found component %s for aux name %s\n",
+ __func__, component->name,
+ codec_info->auxs[j].codec_name);
+ soc_aux->dlc.name = component->name;
+ } else {
+ soc_aux->dlc.name = codec_info->auxs[j].codec_name;
+ }
soc_aux++;
}
--
2.50.1 (Apple Git-155)

View File

@ -0,0 +1,62 @@
From 69e69e240e71e94b8404b33ce9296967a1114258 Mon Sep 17 00:00:00 2001
From: Jaroslav Kysela <jkysela@redhat.com>
Date: Thu, 5 Mar 2026 15:06:06 +0100
Subject: [PATCH] ASoC: soc_sdw_utils: remove index from sdca codec name
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
JIRA: https://issues.redhat.com/browse/RHEL-85741
commit 34b4fc44e4f904fbb81335d53163ffdcb0180000
Author: Bard Liao <yung-chuan.liao@linux.intel.com>
Date: Wed Feb 25 21:50:04 2026 +0800
ASoC: soc_sdw_utils: remove index from sdca codec name
The index is not fixed and it will lead to the DAI link can't bind the
codec component with the name when the index is different from the
predefined one.
Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Reviewed-by: Charles Keepax <ckeepax@opensource.cirrus.com>
Reviewed-by: Péter Ujfalusi <peter.ujfalusi@linux.intel.com>
Link: https://patch.msgid.link/20260225135004.2322987-4-yung-chuan.liao@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Jaroslav Kysela <jkysela@redhat.com>
diff --git a/sound/soc/sdw_utils/soc_sdw_utils.c b/sound/soc/sdw_utils/soc_sdw_utils.c
index 88afb14e1ed3..7afd8fa305be 100644
--- a/sound/soc/sdw_utils/soc_sdw_utils.c
+++ b/sound/soc/sdw_utils/soc_sdw_utils.c
@@ -727,7 +727,7 @@ struct asoc_sdw_codec_info codec_info_list[] = {
.dais = {
{
.direction = {true, false},
- .codec_name = "snd_soc_sdca.UAJ.1",
+ .codec_name = "snd_soc_sdca.UAJ",
.dai_name = "IT 41",
.dai_type = SOC_SDW_DAI_TYPE_JACK,
.dailink = {SOC_SDW_JACK_OUT_DAI_ID, SOC_SDW_UNUSED_DAI_ID},
@@ -743,7 +743,7 @@ struct asoc_sdw_codec_info codec_info_list[] = {
},
{
.direction = {false, true},
- .codec_name = "snd_soc_sdca.UAJ.1",
+ .codec_name = "snd_soc_sdca.UAJ",
.dai_name = "OT 36",
.dai_type = SOC_SDW_DAI_TYPE_JACK,
.dailink = {SOC_SDW_UNUSED_DAI_ID, SOC_SDW_JACK_IN_DAI_ID},
@@ -752,7 +752,7 @@ struct asoc_sdw_codec_info codec_info_list[] = {
.dai_num = 3,
.auxs = {
{
- .codec_name = "snd_soc_sdca.HID.2",
+ .codec_name = "snd_soc_sdca.HID",
},
},
.aux_num = 1,
--
2.50.1 (Apple Git-155)

View File

@ -0,0 +1,33 @@
diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c
index 0349e26..dbd06bd 100644
--- a/arch/x86/kvm/mmu/mmu.c
+++ b/arch/x86/kvm/mmu/mmu.c
@@ -3040,12 +3040,6 @@ static int mmu_set_spte(struct kvm_vcpu *vcpu, struct kvm_memory_slot *slot,
bool prefetch = !fault || fault->prefetch;
bool write_fault = fault && fault->write;
- if (unlikely(is_noslot_pfn(pfn))) {
- vcpu->stat.pf_mmio_spte_created++;
- mark_mmio_spte(vcpu, sptep, gfn, pte_access);
- return RET_PF_EMULATE;
- }
-
if (is_shadow_present_pte(*sptep)) {
if (prefetch && is_last_spte(*sptep, level) &&
pfn == spte_to_pfn(*sptep))
@@ -3069,6 +3063,14 @@ static int mmu_set_spte(struct kvm_vcpu *vcpu, struct kvm_memory_slot *slot,
was_rmapped = 1;
}
+ if (unlikely(is_noslot_pfn(pfn))) {
+ vcpu->stat.pf_mmio_spte_created++;
+ mark_mmio_spte(vcpu, sptep, gfn, pte_access);
+ if (flush)
+ kvm_flush_remote_tlbs_gfn(vcpu->kvm, gfn, level);
+ return RET_PF_EMULATE;
+ }
+
wrprot = make_spte(vcpu, sp, slot, pte_access, gfn, pfn, *sptep, prefetch,
false, host_writable, &spte);

View File

@ -0,0 +1,55 @@
From df83746075778958954aa0460cca55f4b3fc9c02 Mon Sep 17 00:00:00 2001
From: Sean Christopherson <seanjc@google.com>
Date: Thu, 5 Mar 2026 17:42:14 -0800
Subject: [PATCH] KVM: x86/mmu: Only WARN in direct MMUs when overwriting
shadow-present SPTE
Adjust KVM's sanity check against overwriting a shadow-present SPTE with a
another SPTE with a different target PFN to only apply to direct MMUs,
i.e. only to MMUs without shadowed gPTEs. While it's impossible for KVM
to overwrite a shadow-present SPTE in response to a guest write, writes
from outside the scope of KVM, e.g. from host userspace, aren't detected
by KVM's write tracking and so can break KVM's shadow paging rules.
------------[ cut here ]------------
pfn != spte_to_pfn(*sptep)
WARNING: arch/x86/kvm/mmu/mmu.c:3069 at mmu_set_spte+0x1e4/0x440 [kvm], CPU#0: vmx_ept_stale_r/872
Modules linked in: kvm_intel kvm irqbypass
CPU: 0 UID: 1000 PID: 872 Comm: vmx_ept_stale_r Not tainted 7.0.0-rc2-eafebd2d2ab0-sink-vm #319 PREEMPT
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 0.0.0 02/06/2015
RIP: 0010:mmu_set_spte+0x1e4/0x440 [kvm]
Call Trace:
<TASK>
ept_page_fault+0x535/0x7f0 [kvm]
kvm_mmu_do_page_fault+0xee/0x1f0 [kvm]
kvm_mmu_page_fault+0x8d/0x620 [kvm]
vmx_handle_exit+0x18c/0x5a0 [kvm_intel]
kvm_arch_vcpu_ioctl_run+0xc55/0x1c20 [kvm]
kvm_vcpu_ioctl+0x2d5/0x980 [kvm]
__x64_sys_ioctl+0x8a/0xd0
do_syscall_64+0xb5/0x730
entry_SYSCALL_64_after_hwframe+0x4b/0x53
</TASK>
---[ end trace 0000000000000000 ]---
Fixes: 11d45175111d ("KVM: x86/mmu: Warn if PFN changes on shadow-present SPTE in shadow MMU")
Cc: stable@vger.kernel.org
Signed-off-by: Sean Christopherson <seanjc@google.com>
diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c
index 98406d6aa2d6..dd06453d5b72 100644
--- a/arch/x86/kvm/mmu/mmu.c
+++ b/arch/x86/kvm/mmu/mmu.c
@@ -3060,7 +3060,8 @@ static int mmu_set_spte(struct kvm_vcpu *vcpu, struct kvm_memory_slot *slot,
child = spte_to_child_sp(pte);
drop_parent_pte(vcpu->kvm, child, sptep);
flush = true;
- } else if (WARN_ON_ONCE(pfn != spte_to_pfn(*sptep))) {
+ } else if (pfn != spte_to_pfn(*sptep)) {
+ WARN_ON_ONCE(vcpu->arch.mmu->root_role.direct);
drop_spte(vcpu->kvm, sptep);
flush = true;
} else
--
2.50.1 (Apple Git-155)

View File

@ -0,0 +1,101 @@
From 180018072a6bc00717f4648cf45b1dd27752a4ac Mon Sep 17 00:00:00 2001
From: CKI Backport Bot <cki-ci-bot+cki-gitlab-backport-bot@redhat.com>
Date: Wed, 15 Apr 2026 14:04:07 +0000
Subject: [PATCH] nfsd: fix heap overflow in NFSv4.0 LOCK replay cache
JIRA: https://redhat.atlassian.net/browse/RHEL-168570
CVE: CVE-2026-31402
commit 5133b61aaf437e5f25b1b396b14242a6bb0508e2
Author: Jeff Layton <jlayton@kernel.org>
Date: Tue Feb 24 11:33:35 2026 -0500
nfsd: fix heap overflow in NFSv4.0 LOCK replay cache
The NFSv4.0 replay cache uses a fixed 112-byte inline buffer
(rp_ibuf[NFSD4_REPLAY_ISIZE]) to store encoded operation responses.
This size was calculated based on OPEN responses and does not account
for LOCK denied responses, which include the conflicting lock owner as
a variable-length field up to 1024 bytes (NFS4_OPAQUE_LIMIT).
When a LOCK operation is denied due to a conflict with an existing lock
that has a large owner, nfsd4_encode_operation() copies the full encoded
response into the undersized replay buffer via read_bytes_from_xdr_buf()
with no bounds check. This results in a slab-out-of-bounds write of up
to 944 bytes past the end of the buffer, corrupting adjacent heap memory.
This can be triggered remotely by an unauthenticated attacker with two
cooperating NFSv4.0 clients: one sets a lock with a large owner string,
then the other requests a conflicting lock to provoke the denial.
We could fix this by increasing NFSD4_REPLAY_ISIZE to allow for a full
opaque, but that would increase the size of every stateowner, when most
lockowners are not that large.
Instead, fix this by checking the encoded response length against
NFSD4_REPLAY_ISIZE before copying into the replay buffer. If the
response is too large, set rp_buflen to 0 to skip caching the replay
payload. The status is still cached, and the client already received the
correct response on the original request.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc: stable@kernel.org
Reported-by: Nicholas Carlini <npc@anthropic.com>
Tested-by: Nicholas Carlini <npc@anthropic.com>
Signed-off-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: CKI Backport Bot <cki-ci-bot+cki-gitlab-backport-bot@redhat.com>
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index bdf18ffb0064..538806e45904 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -5921,9 +5921,14 @@ nfsd4_encode_operation(struct nfsd4_compoundres *resp, struct nfsd4_op *op)
int len = xdr->buf->len - (op_status_offset + XDR_UNIT);
so->so_replay.rp_status = op->status;
- so->so_replay.rp_buflen = len;
- read_bytes_from_xdr_buf(xdr->buf, op_status_offset + XDR_UNIT,
+ if (len <= NFSD4_REPLAY_ISIZE) {
+ so->so_replay.rp_buflen = len;
+ read_bytes_from_xdr_buf(xdr->buf,
+ op_status_offset + XDR_UNIT,
so->so_replay.rp_buf, len);
+ } else {
+ so->so_replay.rp_buflen = 0;
+ }
}
status:
op->status = nfsd4_map_status(op->status,
diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h
index 399815d9038f..c63c8abd199a 100644
--- a/fs/nfsd/state.h
+++ b/fs/nfsd/state.h
@@ -539,11 +539,18 @@ struct nfs4_client_reclaim {
struct xdr_netobj cr_princhash;
};
-/* A reasonable value for REPLAY_ISIZE was estimated as follows:
- * The OPEN response, typically the largest, requires
- * 4(status) + 8(stateid) + 20(changeinfo) + 4(rflags) + 8(verifier) +
- * 4(deleg. type) + 8(deleg. stateid) + 4(deleg. recall flag) +
- * 20(deleg. space limit) + ~32(deleg. ace) = 112 bytes
+/*
+ * REPLAY_ISIZE is sized for an OPEN response with delegation:
+ * 4(status) + 8(stateid) + 20(changeinfo) + 4(rflags) +
+ * 8(verifier) + 4(deleg. type) + 8(deleg. stateid) +
+ * 4(deleg. recall flag) + 20(deleg. space limit) +
+ * ~32(deleg. ace) = 112 bytes
+ *
+ * Some responses can exceed this. A LOCK denial includes the conflicting
+ * lock owner, which can be up to 1024 bytes (NFS4_OPAQUE_LIMIT). Responses
+ * larger than REPLAY_ISIZE are not cached in rp_ibuf; only rp_status is
+ * saved. Enlarging this constant increases the size of every
+ * nfs4_stateowner.
*/
#define NFSD4_REPLAY_ISIZE 112
--
2.50.1 (Apple Git-155)

View File

@ -0,0 +1,35 @@
From 8df832e6b945e1ba61467d7f1c9305e314ae92fe Mon Sep 17 00:00:00 2001
From: Ignat Korchagin <ignat@cloudflare.com>
Date: Mon, 14 Oct 2024 16:38:03 +0100
Subject: [PATCH] net: af_can: do not leave a dangling sk pointer in
can_create()
[ Upstream commit 811a7ca7320c062e15d0f5b171fe6ad8592d1434 ]
On error can_create() frees the allocated sk object, but sock_init_data()
has already attached it to the provided sock object. This will leave a
dangling sk pointer in the sock object and may cause use-after-free later.
Signed-off-by: Ignat Korchagin <ignat@cloudflare.com>
Reviewed-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
Reviewed-by: Kuniyuki Iwashima <kuniyu@amazon.com>
Reviewed-by: Marc Kleine-Budde <mkl@pengutronix.de>
Link: https://patch.msgid.link/20241014153808.51894-5-ignat@cloudflare.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
diff --git a/net/can/af_can.c b/net/can/af_can.c
index 707576eeeb58..01f3fbb3b67d 100644
--- a/net/can/af_can.c
+++ b/net/can/af_can.c
@@ -171,6 +171,7 @@ static int can_create(struct net *net, struct socket *sock, int protocol,
/* release sk on errors */
sock_orphan(sk);
sock_put(sk);
+ sock->sk = NULL;
}
errout:
--
2.50.1 (Apple Git-155)

View File

@ -0,0 +1,66 @@
From b9cdc1763c2f19e5d5f025e13cd0ccb71aa44616 Mon Sep 17 00:00:00 2001
From: CKI Backport Bot <cki-ci-bot+cki-gitlab-backport-bot@redhat.com>
Date: Mon, 20 Apr 2026 15:21:10 +0000
Subject: [PATCH] crypto: asymmetric_keys - prevent overflow in
asymmetric_key_generate_id
JIRA: https://redhat.atlassian.net/browse/RHEL-169566
CVE: CVE-2025-68724
commit df0845cf447ae1556c3440b8b155de0926cbaa56
Author: Thorsten Blum <thorsten.blum@linux.dev>
Date: Mon Oct 13 13:40:10 2025 +0200
crypto: asymmetric_keys - prevent overflow in asymmetric_key_generate_id
Use check_add_overflow() to guard against potential integer overflows
when adding the binary blob lengths and the size of an asymmetric_key_id
structure and return ERR_PTR(-EOVERFLOW) accordingly. This prevents a
possible buffer overflow when copying data from potentially malicious
X.509 certificate fields that can be arbitrarily large, such as ASN.1
INTEGER serial numbers, issuer names, etc.
Fixes: 7901c1a8effb ("KEYS: Implement binary asymmetric key ID handling")
Signed-off-by: Thorsten Blum <thorsten.blum@linux.dev>
Reviewed-by: Lukas Wunner <lukas@wunner.de>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: CKI Backport Bot <cki-ci-bot+cki-gitlab-backport-bot@redhat.com>
diff --git a/crypto/asymmetric_keys/asymmetric_type.c b/crypto/asymmetric_keys/asymmetric_type.c
index 43af5fa510c0..7859b0692b42 100644
--- a/crypto/asymmetric_keys/asymmetric_type.c
+++ b/crypto/asymmetric_keys/asymmetric_type.c
@@ -11,6 +11,7 @@
#include <crypto/public_key.h>
#include <linux/seq_file.h>
#include <linux/module.h>
+#include <linux/overflow.h>
#include <linux/slab.h>
#include <linux/ctype.h>
#include <keys/system_keyring.h>
@@ -151,12 +152,17 @@ struct asymmetric_key_id *asymmetric_key_generate_id(const void *val_1,
size_t len_2)
{
struct asymmetric_key_id *kid;
-
- kid = kmalloc(sizeof(struct asymmetric_key_id) + len_1 + len_2,
- GFP_KERNEL);
+ size_t kid_sz;
+ size_t len;
+
+ if (check_add_overflow(len_1, len_2, &len))
+ return ERR_PTR(-EOVERFLOW);
+ if (check_add_overflow(sizeof(struct asymmetric_key_id), len, &kid_sz))
+ return ERR_PTR(-EOVERFLOW);
+ kid = kmalloc(kid_sz, GFP_KERNEL);
if (!kid)
return ERR_PTR(-ENOMEM);
- kid->len = len_1 + len_2;
+ kid->len = len;
memcpy(kid->data, val_1, len_1);
memcpy(kid->data + len_1, val_2, len_2);
return kid;
--
2.50.1 (Apple Git-155)

View File

@ -0,0 +1,81 @@
From c88e70dc8bfca9a2be74a100387b1b66de973128 Mon Sep 17 00:00:00 2001
From: Imre Deak <imre.deak@intel.com>
Date: Wed, 15 Oct 2025 19:19:28 +0300
Subject: [PATCH] drm/i915/dsc: Add helper to enable the DSC configuration for
a CRTC
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Add a helper to enable the DSC compression configuration for a CRTC.
Follow-up changes will introduce tracking for the same DSC state on the
whole link, which will need to be set whenever DSC is enabled for the
CRTC. Also, according to the above, when querying the DSC state on the
link, both the CRTC's and the link's DSC state must be considered.
Setting the DSC configuration for a CRTC and querying the DSC
configuration for the link (added by follow-up changes) is better done
via helper functions based on the above, prepare for that here.
Signed-off-by: Imre Deak <imre.deak@intel.com>
Reviewed-by: Jouni Högander <jouni.hogander@intel.com>
Link: https://lore.kernel.org/r/20251015161934.262108-2-imre.deak@intel.com
diff --git a/drivers/gpu/drm/i915/display/icl_dsi.c b/drivers/gpu/drm/i915/display/icl_dsi.c
index 37faa8f19f6e..297368ff42a5 100644
--- a/drivers/gpu/drm/i915/display/icl_dsi.c
+++ b/drivers/gpu/drm/i915/display/icl_dsi.c
@@ -1655,7 +1655,7 @@ static int gen11_dsi_dsc_compute_config(struct intel_encoder *encoder,
if (ret)
return ret;
- crtc_state->dsc.compression_enable = true;
+ intel_dsc_enable_on_crtc(crtc_state);
return 0;
}
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index 7059d55687cf..fc1949e0c4de 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -2475,7 +2475,8 @@ int intel_dp_dsc_compute_config(struct intel_dp *intel_dp,
return ret;
}
- pipe_config->dsc.compression_enable = true;
+ intel_dsc_enable_on_crtc(pipe_config);
+
drm_dbg_kms(display->drm, "DP DSC computed with Input Bpp = %d "
"Compressed Bpp = " FXP_Q4_FMT " Slice Count = %d\n",
pipe_config->pipe_bpp,
diff --git a/drivers/gpu/drm/i915/display/intel_vdsc.c b/drivers/gpu/drm/i915/display/intel_vdsc.c
index bca747e24a7f..803f3b395c79 100644
--- a/drivers/gpu/drm/i915/display/intel_vdsc.c
+++ b/drivers/gpu/drm/i915/display/intel_vdsc.c
@@ -372,6 +372,11 @@ int intel_dsc_compute_params(struct intel_crtc_state *pipe_config)
return 0;
}
+void intel_dsc_enable_on_crtc(struct intel_crtc_state *crtc_state)
+{
+ crtc_state->dsc.compression_enable = true;
+}
+
enum intel_display_power_domain
intel_dsc_power_domain(struct intel_crtc *crtc, enum transcoder cpu_transcoder)
{
diff --git a/drivers/gpu/drm/i915/display/intel_vdsc.h b/drivers/gpu/drm/i915/display/intel_vdsc.h
index 2139391ff881..8c7c7fb652c3 100644
--- a/drivers/gpu/drm/i915/display/intel_vdsc.h
+++ b/drivers/gpu/drm/i915/display/intel_vdsc.h
@@ -20,6 +20,7 @@ void intel_uncompressed_joiner_enable(const struct intel_crtc_state *crtc_state)
void intel_dsc_enable(const struct intel_crtc_state *crtc_state);
void intel_dsc_disable(const struct intel_crtc_state *crtc_state);
int intel_dsc_compute_params(struct intel_crtc_state *pipe_config);
+void intel_dsc_enable_on_crtc(struct intel_crtc_state *crtc_state);
void intel_dsc_get_config(struct intel_crtc_state *crtc_state);
enum intel_display_power_domain
intel_dsc_power_domain(struct intel_crtc *crtc, enum transcoder cpu_transcoder);
--
2.50.1 (Apple Git-155)

View File

@ -0,0 +1,90 @@
From 69df31263bcabc527a5b526fb8972cb080a179b3 Mon Sep 17 00:00:00 2001
From: Imre Deak <imre.deak@intel.com>
Date: Wed, 15 Oct 2025 19:19:29 +0300
Subject: [PATCH] drm/i915/dp: Ensure the FEC state stays disabled for UHBR
links
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Atm, in the DP SST case the FEC state is computed before
intel_crtc_state::port_clock is initialized, hence intel_dp_is_uhbr()
will always return false and the FEC state will be always computed
assuming a non-UHBR link.
This happens to work, since the FEC state is recomputed later in
intel_dp_mtp_tu_compute_config(), where port_clock will be set already,
so intel_crtc_state::fec_enable will be reset as expected for UHBR. This
also depends on link rates being tried in an increasing order (i.e. from
non-UHBR -> UHBR link rates) in dsc_compute_link_config(), thus
intel_crtc_state::fec_enable being set for the non-UHBR rates and
getting reset for the first UHBR rate as expected.
A follow-up change will reuse intel_dp_fec_compute_config() for the DP
MST state computation, prepare for that here, making sure that the
function determines the correct intel_crtc_state::fec_enable=false state
for UHBR link rates based on the above.
The DP SST and MST state computation should be further unified to avoid
computing/setting the intel_crtc_state::fec_enable state multiple times,
but that's left for a follow-up change. For now add only code comments
about this.
Signed-off-by: Imre Deak <imre.deak@intel.com>
Reviewed-by: Jouni Högander <jouni.hogander@intel.com>
Link: https://lore.kernel.org/r/20251015161934.262108-3-imre.deak@intel.com
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index fc1949e0c4de..7c568c23134f 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -2368,6 +2368,9 @@ static int intel_edp_dsc_compute_pipe_bpp(struct intel_dp *intel_dp,
static void intel_dp_fec_compute_config(struct intel_dp *intel_dp,
struct intel_crtc_state *crtc_state)
{
+ if (intel_dp_is_uhbr(crtc_state))
+ return;
+
if (crtc_state->fec_enable)
return;
@@ -2379,9 +2382,6 @@ static void intel_dp_fec_compute_config(struct intel_dp *intel_dp,
if (intel_dp_is_edp(intel_dp))
return;
- if (intel_dp_is_uhbr(crtc_state))
- return;
-
crtc_state->fec_enable = true;
}
@@ -2400,6 +2400,10 @@ int intel_dp_dsc_compute_config(struct intel_dp *intel_dp,
bool is_mst = intel_crtc_has_type(pipe_config, INTEL_OUTPUT_DP_MST);
int ret;
+ /*
+ * FIXME: set the FEC enabled state once pipe_config->port_clock is
+ * already known, so the UHBR/non-UHBR mode can be determined.
+ */
intel_dp_fec_compute_config(intel_dp, pipe_config);
if (!intel_dp_dsc_supports_format(connector, pipe_config->output_format))
diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c
index f2266b265304..27e952a67c34 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
@@ -293,6 +293,11 @@ int intel_dp_mtp_tu_compute_config(struct intel_dp *intel_dp,
mst_stream_update_slots(crtc_state, mst_state);
}
+ /*
+ * NOTE: The following must reset crtc_state->fec_enable for UHBR/DSC
+ * after it was set by intel_dp_dsc_compute_config() ->
+ * intel_dp_fec_compute_config().
+ */
if (dsc) {
if (!intel_dp_supports_fec(intel_dp, connector, crtc_state))
return -EINVAL;
--
2.50.1 (Apple Git-155)

View File

@ -0,0 +1,106 @@
From cb6c8f1f6f46ac2cbfb42ce8eb8b18257aeaa91a Mon Sep 17 00:00:00 2001
From: Imre Deak <imre.deak@intel.com>
Date: Wed, 15 Oct 2025 19:19:30 +0300
Subject: [PATCH] drm/i915/dp: Export helper to determine if FEC on non-UHBR
links is required
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Export the helper function to determine if FEC is required on a non-UHBR
(8b10b) SST or MST link. A follow up change will take this into use for
MST as well.
While at it determine the output type from the CRTC state, which allows
dropping the intel_dp argument. Also make the function return the
required FEC state, instead of setting this in the CRTC state, which
allows only querying this requirement, without changing the state.
Also rename the function to intel_dp_needs_8b10b_fec(), to clarify that
the function determines if FEC is required on an 8b10b link (on 128b132b
links FEC is always enabled by the HW implicitly, so the function will
return false for that case).
Signed-off-by: Imre Deak <imre.deak@intel.com>
Reviewed-by: Jouni Högander <jouni.hogander@intel.com>
Link: https://lore.kernel.org/r/20251015161934.262108-4-imre.deak@intel.com
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index 7c568c23134f..844118735998 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -2365,24 +2365,29 @@ static int intel_edp_dsc_compute_pipe_bpp(struct intel_dp *intel_dp,
return 0;
}
-static void intel_dp_fec_compute_config(struct intel_dp *intel_dp,
- struct intel_crtc_state *crtc_state)
+/*
+ * Return whether FEC must be enabled for 8b10b SST or MST links. On 128b132b
+ * links FEC is always enabled implicitly by the HW, so this function returns
+ * false for that case.
+ */
+bool intel_dp_needs_8b10b_fec(const struct intel_crtc_state *crtc_state,
+ bool dsc_enabled_on_crtc)
{
if (intel_dp_is_uhbr(crtc_state))
- return;
+ return false;
if (crtc_state->fec_enable)
- return;
+ return true;
/*
* Though eDP v1.5 supports FEC with DSC, unlike DP, it is optional.
* Since, FEC is a bandwidth overhead, continue to not enable it for
* eDP. Until, there is a good reason to do so.
*/
- if (intel_dp_is_edp(intel_dp))
- return;
+ if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP))
+ return false;
- crtc_state->fec_enable = true;
+ return dsc_enabled_on_crtc;
}
int intel_dp_dsc_compute_config(struct intel_dp *intel_dp,
@@ -2404,7 +2409,7 @@ int intel_dp_dsc_compute_config(struct intel_dp *intel_dp,
* FIXME: set the FEC enabled state once pipe_config->port_clock is
* already known, so the UHBR/non-UHBR mode can be determined.
*/
- intel_dp_fec_compute_config(intel_dp, pipe_config);
+ pipe_config->fec_enable = intel_dp_needs_8b10b_fec(pipe_config, true);
if (!intel_dp_dsc_supports_format(connector, pipe_config->output_format))
return -EINVAL;
diff --git a/drivers/gpu/drm/i915/display/intel_dp.h b/drivers/gpu/drm/i915/display/intel_dp.h
index 281ced3a3b39..0537be20fe7b 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.h
+++ b/drivers/gpu/drm/i915/display/intel_dp.h
@@ -73,6 +73,8 @@ void intel_dp_encoder_flush_work(struct drm_encoder *encoder);
int intel_dp_compute_config(struct intel_encoder *encoder,
struct intel_crtc_state *pipe_config,
struct drm_connector_state *conn_state);
+bool intel_dp_needs_8b10b_fec(const struct intel_crtc_state *crtc_state,
+ bool dsc_enabled_on_crtc);
int intel_dp_dsc_compute_config(struct intel_dp *intel_dp,
struct intel_crtc_state *pipe_config,
struct drm_connector_state *conn_state,
diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c
index 27e952a67c34..d0590b5ffffd 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
@@ -296,7 +296,7 @@ int intel_dp_mtp_tu_compute_config(struct intel_dp *intel_dp,
/*
* NOTE: The following must reset crtc_state->fec_enable for UHBR/DSC
* after it was set by intel_dp_dsc_compute_config() ->
- * intel_dp_fec_compute_config().
+ * intel_dp_needs_8b10b_fec().
*/
if (dsc) {
if (!intel_dp_supports_fec(intel_dp, connector, crtc_state))
--
2.50.1 (Apple Git-155)

View File

@ -0,0 +1,40 @@
From b762ae48293e2cc2145cdc91eb596d057f1aff11 Mon Sep 17 00:00:00 2001
From: Imre Deak <imre.deak@intel.com>
Date: Wed, 15 Oct 2025 19:19:31 +0300
Subject: [PATCH] drm/i915/dp_mst: Reuse the DP-SST helper function to compute
FEC config
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Reuse the DP-SST helper to compute the state for the FEC enabled state
for DP-MST as well.
Signed-off-by: Imre Deak <imre.deak@intel.com>
Reviewed-by: Jouni Högander <jouni.hogander@intel.com>
Link: https://lore.kernel.org/r/20251015161934.262108-5-imre.deak@intel.com
diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c
index d0590b5ffffd..0cbb4c3a8e22 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
@@ -298,12 +298,10 @@ int intel_dp_mtp_tu_compute_config(struct intel_dp *intel_dp,
* after it was set by intel_dp_dsc_compute_config() ->
* intel_dp_needs_8b10b_fec().
*/
- if (dsc) {
- if (!intel_dp_supports_fec(intel_dp, connector, crtc_state))
- return -EINVAL;
-
- crtc_state->fec_enable = !intel_dp_is_uhbr(crtc_state);
- }
+ crtc_state->fec_enable = intel_dp_needs_8b10b_fec(crtc_state, dsc);
+ if (crtc_state->fec_enable &&
+ !intel_dp_supports_fec(intel_dp, connector, crtc_state))
+ return -EINVAL;
max_dpt_bpp_x16 = fxp_q4_from_int(intel_dp_mst_max_dpt_bpp(crtc_state, dsc));
if (max_dpt_bpp_x16 && max_bpp_x16 > max_dpt_bpp_x16) {
--
2.50.1 (Apple Git-155)

View File

@ -0,0 +1,100 @@
From 7c027070e98d7b515e4d3a94b54d288c61cb5918 Mon Sep 17 00:00:00 2001
From: Imre Deak <imre.deak@intel.com>
Date: Wed, 15 Oct 2025 19:19:32 +0300
Subject: [PATCH] drm/i915/dp_mst: Track DSC enabled status on the MST link
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Track whether DSC is enabled on any CRTC on a link. On DP-SST (and DSI)
this will always match the CRTC's DSC state, those links having only a
single stream (aka CRTC). For instance, on DP-MST if DSC is enabled for
CRTC#0, but disabled for CRTC#1, the DSC/FEC state for these CRTCs will
be as follows:
CRTC#0:
- compression_enable = true
- compression_enabled_on_link = true
- fec_enable = true for 8b10b, false for 128b132b
CRTC#1:
- compression_enable = false
- compression_enabled_on_link = true
- fec_enable = true for 8b10b, false for 128b132b
This patch only sets compression_enabled_on_link for CRTC#0 above and
enables FEC on CRTC#0 if DSC was enabled on any other CRTC on the 8b10b
MST link. A follow-up change will make sure that the state of all the
CRTCs (CRTC#1 above) on an MST link is recomputed if DSC gets enabled on
any CRTC, setting compression_enabled_on_link and fec_enable for these.
Signed-off-by: Imre Deak <imre.deak@intel.com>
Reviewed-by: Jouni Högander <jouni.hogander@intel.com>
Link: https://lore.kernel.org/r/20251015161934.262108-6-imre.deak@intel.com
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index 203dd38a9ec4..20747fa4d3da 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -1279,6 +1279,8 @@ struct intel_crtc_state {
/* Display Stream compression state */
struct {
+ /* Only used for state computation, not read out from the HW. */
+ bool compression_enabled_on_link;
bool compression_enable;
int num_streams;
/* Compressed Bpp in U6.4 format (first 4 bits for fractional part) */
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index 844118735998..95884af242b3 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -2387,7 +2387,7 @@ bool intel_dp_needs_8b10b_fec(const struct intel_crtc_state *crtc_state,
if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP))
return false;
- return dsc_enabled_on_crtc;
+ return dsc_enabled_on_crtc || intel_dsc_enabled_on_link(crtc_state);
}
int intel_dp_dsc_compute_config(struct intel_dp *intel_dp,
diff --git a/drivers/gpu/drm/i915/display/intel_vdsc.c b/drivers/gpu/drm/i915/display/intel_vdsc.c
index 803f3b395c79..dbf2cf1b896d 100644
--- a/drivers/gpu/drm/i915/display/intel_vdsc.c
+++ b/drivers/gpu/drm/i915/display/intel_vdsc.c
@@ -374,9 +374,20 @@ int intel_dsc_compute_params(struct intel_crtc_state *pipe_config)
void intel_dsc_enable_on_crtc(struct intel_crtc_state *crtc_state)
{
+ crtc_state->dsc.compression_enabled_on_link = true;
crtc_state->dsc.compression_enable = true;
}
+bool intel_dsc_enabled_on_link(const struct intel_crtc_state *crtc_state)
+{
+ struct intel_display *display = to_intel_display(crtc_state);
+
+ drm_WARN_ON(display->drm, crtc_state->dsc.compression_enable &&
+ !crtc_state->dsc.compression_enabled_on_link);
+
+ return crtc_state->dsc.compression_enabled_on_link;
+}
+
enum intel_display_power_domain
intel_dsc_power_domain(struct intel_crtc *crtc, enum transcoder cpu_transcoder)
{
diff --git a/drivers/gpu/drm/i915/display/intel_vdsc.h b/drivers/gpu/drm/i915/display/intel_vdsc.h
index 8c7c7fb652c3..99f64ac54b27 100644
--- a/drivers/gpu/drm/i915/display/intel_vdsc.h
+++ b/drivers/gpu/drm/i915/display/intel_vdsc.h
@@ -21,6 +21,7 @@ void intel_dsc_enable(const struct intel_crtc_state *crtc_state);
void intel_dsc_disable(const struct intel_crtc_state *crtc_state);
int intel_dsc_compute_params(struct intel_crtc_state *pipe_config);
void intel_dsc_enable_on_crtc(struct intel_crtc_state *crtc_state);
+bool intel_dsc_enabled_on_link(const struct intel_crtc_state *crtc_state);
void intel_dsc_get_config(struct intel_crtc_state *crtc_state);
enum intel_display_power_domain
intel_dsc_power_domain(struct intel_crtc *crtc, enum transcoder cpu_transcoder);
--
2.50.1 (Apple Git-155)

View File

@ -0,0 +1,171 @@
From 470b84af457e34cbfa4d2c17dab78746736ab898 Mon Sep 17 00:00:00 2001
From: Imre Deak <imre.deak@intel.com>
Date: Wed, 15 Oct 2025 19:19:33 +0300
Subject: [PATCH] drm/i915/dp_mst: Recompute all MST link CRTCs if DSC gets
enabled on the link
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The state of all the CRTCs on an MST link must be recomputed, if DSC
gets enabled on any of the CRTCs on the link. For instance an MST
docking station's Panel Replay capability may depend on whether DSC is
enabled on any of the dock's streams (aka CRTCs). To assist the Panel
Replay state computation for a CRTC based on the above, track in the
CRTC state if DSC is enabled on any CRTC on an MST link.
The intel_link_bw_limits::force_fec_pipes mask is used for a reason
similar to the above: enable FEC on all CRTCs of a non-UHBR (8b10b) MST
link if DSC is enabled on any of the link's CRTCs. The FEC enabled state
for a CRTC doesn't indicate if DSC is enabled on a UHBR MST link (FEC is
always enabled by the HW for UHBR, hence it's not tracked by the
intel_crtc_state::fec_enable flag for such links, where this flag is
always false).
Based on the above, to be able to determine the DSC state on both
non-UHBR and UHBR MST links, track the more generic DSC-enabled-on-link
state (instead of the FEC-enabled-on-link state) for each CRTC in
intel_link_bw_limits.
Signed-off-by: Imre Deak <imre.deak@intel.com>
Reviewed-by: Jouni Högander <jouni.hogander@intel.com>
Link: https://lore.kernel.org/r/20251015161934.262108-7-imre.deak@intel.com
diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index bbb6ff929d64..a8b4619de347 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -4603,7 +4603,7 @@ intel_modeset_pipe_config(struct intel_atomic_state *state,
if (ret)
return ret;
- crtc_state->fec_enable = limits->force_fec_pipes & BIT(crtc->pipe);
+ crtc_state->dsc.compression_enabled_on_link = limits->link_dsc_pipes & BIT(crtc->pipe);
crtc_state->max_link_bpp_x16 = limits->max_bpp_x16[crtc->pipe];
if (crtc_state->pipe_bpp > fxp_q4_to_int(crtc_state->max_link_bpp_x16)) {
diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c
index 0cbb4c3a8e22..a845b2612a3f 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
@@ -814,14 +814,14 @@ static u8 get_pipes_downstream_of_mst_port(struct intel_atomic_state *state,
return mask;
}
-static int intel_dp_mst_check_fec_change(struct intel_atomic_state *state,
+static int intel_dp_mst_check_dsc_change(struct intel_atomic_state *state,
struct drm_dp_mst_topology_mgr *mst_mgr,
struct intel_link_bw_limits *limits)
{
struct intel_display *display = to_intel_display(state);
struct intel_crtc *crtc;
u8 mst_pipe_mask;
- u8 fec_pipe_mask = 0;
+ u8 dsc_pipe_mask = 0;
int ret;
mst_pipe_mask = get_pipes_downstream_of_mst_port(state, mst_mgr, NULL);
@@ -834,16 +834,16 @@ static int intel_dp_mst_check_fec_change(struct intel_atomic_state *state,
if (drm_WARN_ON(display->drm, !crtc_state))
return -EINVAL;
- if (crtc_state->fec_enable)
- fec_pipe_mask |= BIT(crtc->pipe);
+ if (intel_dsc_enabled_on_link(crtc_state))
+ dsc_pipe_mask |= BIT(crtc->pipe);
}
- if (!fec_pipe_mask || mst_pipe_mask == fec_pipe_mask)
+ if (!dsc_pipe_mask || mst_pipe_mask == dsc_pipe_mask)
return 0;
- limits->force_fec_pipes |= mst_pipe_mask;
+ limits->link_dsc_pipes |= mst_pipe_mask;
- ret = intel_modeset_pipes_in_mask_early(state, "MST FEC",
+ ret = intel_modeset_pipes_in_mask_early(state, "MST DSC",
mst_pipe_mask);
return ret ? : -EAGAIN;
@@ -897,7 +897,7 @@ int intel_dp_mst_atomic_check_link(struct intel_atomic_state *state,
int i;
for_each_new_mst_mgr_in_state(&state->base, mgr, mst_state, i) {
- ret = intel_dp_mst_check_fec_change(state, mgr, limits);
+ ret = intel_dp_mst_check_dsc_change(state, mgr, limits);
if (ret)
return ret;
diff --git a/drivers/gpu/drm/i915/display/intel_link_bw.c b/drivers/gpu/drm/i915/display/intel_link_bw.c
index f52dee0ea412..d2862de894fa 100644
--- a/drivers/gpu/drm/i915/display/intel_link_bw.c
+++ b/drivers/gpu/drm/i915/display/intel_link_bw.c
@@ -20,6 +20,7 @@
#include "intel_dp_tunnel.h"
#include "intel_fdi.h"
#include "intel_link_bw.h"
+#include "intel_vdsc.h"
static int get_forced_link_bpp_x16(struct intel_atomic_state *state,
const struct intel_crtc *crtc)
@@ -55,7 +56,7 @@ void intel_link_bw_init_limits(struct intel_atomic_state *state,
struct intel_display *display = to_intel_display(state);
enum pipe pipe;
- limits->force_fec_pipes = 0;
+ limits->link_dsc_pipes = 0;
limits->bpp_limit_reached_pipes = 0;
for_each_pipe(display, pipe) {
struct intel_crtc *crtc = intel_crtc_for_pipe(display, pipe);
@@ -65,8 +66,8 @@ void intel_link_bw_init_limits(struct intel_atomic_state *state,
if (state->base.duplicated && crtc_state) {
limits->max_bpp_x16[pipe] = crtc_state->max_link_bpp_x16;
- if (crtc_state->fec_enable)
- limits->force_fec_pipes |= BIT(pipe);
+ if (intel_dsc_enabled_on_link(crtc_state))
+ limits->link_dsc_pipes |= BIT(pipe);
} else {
limits->max_bpp_x16[pipe] = INT_MAX;
}
@@ -265,10 +266,10 @@ assert_link_limit_change_valid(struct intel_display *display,
bool bpps_changed = false;
enum pipe pipe;
- /* FEC can't be forced off after it was forced on. */
+ /* DSC can't be disabled after it was enabled. */
if (drm_WARN_ON(display->drm,
- (old_limits->force_fec_pipes & new_limits->force_fec_pipes) !=
- old_limits->force_fec_pipes))
+ (old_limits->link_dsc_pipes & new_limits->link_dsc_pipes) !=
+ old_limits->link_dsc_pipes))
return false;
for_each_pipe(display, pipe) {
@@ -286,8 +287,8 @@ assert_link_limit_change_valid(struct intel_display *display,
/* At least one limit must change. */
if (drm_WARN_ON(display->drm,
!bpps_changed &&
- new_limits->force_fec_pipes ==
- old_limits->force_fec_pipes))
+ new_limits->link_dsc_pipes ==
+ old_limits->link_dsc_pipes))
return false;
return true;
diff --git a/drivers/gpu/drm/i915/display/intel_link_bw.h b/drivers/gpu/drm/i915/display/intel_link_bw.h
index 95ab7c50c61d..cb18e171037c 100644
--- a/drivers/gpu/drm/i915/display/intel_link_bw.h
+++ b/drivers/gpu/drm/i915/display/intel_link_bw.h
@@ -15,7 +15,7 @@ struct intel_connector;
struct intel_crtc_state;
struct intel_link_bw_limits {
- u8 force_fec_pipes;
+ u8 link_dsc_pipes;
u8 bpp_limit_reached_pipes;
/* in 1/16 bpp units */
int max_bpp_x16[I915_MAX_PIPES];
--
2.50.1 (Apple Git-155)

View File

@ -0,0 +1,248 @@
From c390bf07961b3a39f3417d75850a4e721b87e595 Mon Sep 17 00:00:00 2001
From: Imre Deak <imre.deak@intel.com>
Date: Wed, 15 Oct 2025 19:19:34 +0300
Subject: [PATCH] drm/i915/dp: Fix panel replay when DSC is enabled
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Prevent enabling panel replay if the sink doesn't support this due to
DSC being enabled.
Panel replay has two modes, updating full frames or only selected
regions of the frame. If the sink doesn't support Panel Replay in full
frame update mode with DSC prevent Panel Replay completely if DSC is
enabled. If the sink doesn't support Panel Replay only in the selective
update mode while DSC is enabled, it will still support Panel Replay in
the full frame update mode, so only prevent selective updates in this
case.
v2:
- Use Panel Replay instead of PR in debug prints. (Jouni)
- Rebase on change tracking the link DSC state in the crtc state.
Cc: Jouni Högander <jouni.hogander@intel.com>
Closes: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/14869
Reviewed-by: Jouni Högander <jouni.hogander@intel.com>
Signed-off-by: Imre Deak <imre.deak@intel.com>
Link: https://lore.kernel.org/r/20251015161934.262108-8-imre.deak@intel.com
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index 20747fa4d3da..1e0cd81c9474 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -955,6 +955,12 @@ struct intel_csc_matrix {
u16 postoff[3];
};
+enum intel_panel_replay_dsc_support {
+ INTEL_DP_PANEL_REPLAY_DSC_NOT_SUPPORTED,
+ INTEL_DP_PANEL_REPLAY_DSC_FULL_FRAME_ONLY,
+ INTEL_DP_PANEL_REPLAY_DSC_SELECTIVE_UPDATE,
+};
+
struct intel_crtc_state {
/*
* uapi (drm) state. This is the software state shown to userspace.
@@ -1133,6 +1139,8 @@ struct intel_crtc_state {
bool has_panel_replay;
bool wm_level_disabled;
bool pkg_c_latency_used;
+ /* Only used for state verification. */
+ enum intel_panel_replay_dsc_support panel_replay_dsc_support;
u32 dc3co_exitline;
u16 su_y_granularity;
u8 active_non_psr_pipes;
@@ -1706,6 +1714,7 @@ struct intel_psr {
bool source_panel_replay_support;
bool sink_panel_replay_support;
bool sink_panel_replay_su_support;
+ enum intel_panel_replay_dsc_support sink_panel_replay_dsc_support;
bool panel_replay_enabled;
u32 dc3co_exitline;
u32 dc3co_exit_delay;
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index 95884af242b3..215ad690ab07 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -6053,6 +6053,8 @@ intel_dp_detect(struct drm_connector *_connector,
memset(connector->dp.dsc_dpcd, 0, sizeof(connector->dp.dsc_dpcd));
intel_dp->psr.sink_panel_replay_support = false;
intel_dp->psr.sink_panel_replay_su_support = false;
+ intel_dp->psr.sink_panel_replay_dsc_support =
+ INTEL_DP_PANEL_REPLAY_DSC_NOT_SUPPORTED;
intel_dp_mst_disconnect(intel_dp);
diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c
index 703e5f6af04c..3e99a65ec988 100644
--- a/drivers/gpu/drm/i915/display/intel_psr.c
+++ b/drivers/gpu/drm/i915/display/intel_psr.c
@@ -29,6 +29,7 @@
#include <drm/drm_vblank.h>
#include "i915_reg.h"
+#include "i915_utils.h"
#include "intel_alpm.h"
#include "intel_atomic.h"
#include "intel_crtc.h"
@@ -50,6 +51,7 @@
#include "intel_snps_phy.h"
#include "intel_step.h"
#include "intel_vblank.h"
+#include "intel_vdsc.h"
#include "intel_vrr.h"
#include "skl_universal_plane.h"
@@ -580,6 +582,44 @@ static void intel_dp_get_su_granularity(struct intel_dp *intel_dp)
intel_dp->psr.su_y_granularity = y;
}
+static enum intel_panel_replay_dsc_support
+compute_pr_dsc_support(struct intel_dp *intel_dp)
+{
+ u8 pr_dsc_mode;
+ u8 val;
+
+ val = intel_dp->pr_dpcd[INTEL_PR_DPCD_INDEX(DP_PANEL_REPLAY_CAP_CAPABILITY)];
+ pr_dsc_mode = REG_FIELD_GET8(DP_PANEL_REPLAY_DSC_DECODE_CAPABILITY_IN_PR_MASK, val);
+
+ switch (pr_dsc_mode) {
+ case DP_DSC_DECODE_CAPABILITY_IN_PR_FULL_FRAME_ONLY:
+ return INTEL_DP_PANEL_REPLAY_DSC_FULL_FRAME_ONLY;
+ case DP_DSC_DECODE_CAPABILITY_IN_PR_SUPPORTED:
+ return INTEL_DP_PANEL_REPLAY_DSC_SELECTIVE_UPDATE;
+ default:
+ MISSING_CASE(pr_dsc_mode);
+ fallthrough;
+ case DP_DSC_DECODE_CAPABILITY_IN_PR_NOT_SUPPORTED:
+ case DP_DSC_DECODE_CAPABILITY_IN_PR_RESERVED:
+ return INTEL_DP_PANEL_REPLAY_DSC_NOT_SUPPORTED;
+ }
+}
+
+static const char *panel_replay_dsc_support_str(enum intel_panel_replay_dsc_support dsc_support)
+{
+ switch (dsc_support) {
+ case INTEL_DP_PANEL_REPLAY_DSC_NOT_SUPPORTED:
+ return "not supported";
+ case INTEL_DP_PANEL_REPLAY_DSC_FULL_FRAME_ONLY:
+ return "full frame only";
+ case INTEL_DP_PANEL_REPLAY_DSC_SELECTIVE_UPDATE:
+ return "selective update";
+ default:
+ MISSING_CASE(dsc_support);
+ return "n/a";
+ };
+}
+
static void _panel_replay_init_dpcd(struct intel_dp *intel_dp)
{
struct intel_display *display = to_intel_display(intel_dp);
@@ -615,10 +655,13 @@ static void _panel_replay_init_dpcd(struct intel_dp *intel_dp)
DP_PANEL_REPLAY_SU_SUPPORT)
intel_dp->psr.sink_panel_replay_su_support = true;
+ intel_dp->psr.sink_panel_replay_dsc_support = compute_pr_dsc_support(intel_dp);
+
drm_dbg_kms(display->drm,
- "Panel replay %sis supported by panel\n",
+ "Panel replay %sis supported by panel (in DSC mode: %s)\n",
intel_dp->psr.sink_panel_replay_su_support ?
- "selective_update " : "");
+ "selective_update " : "",
+ panel_replay_dsc_support_str(intel_dp->psr.sink_panel_replay_dsc_support));
}
static void _psr_init_dpcd(struct intel_dp *intel_dp)
@@ -1606,9 +1649,21 @@ static bool intel_sel_update_config_valid(struct intel_dp *intel_dp,
goto unsupported;
}
- if (crtc_state->has_panel_replay && (DISPLAY_VER(display) < 14 ||
- !intel_dp->psr.sink_panel_replay_su_support))
- goto unsupported;
+ if (crtc_state->has_panel_replay) {
+ if (DISPLAY_VER(display) < 14)
+ goto unsupported;
+
+ if (!intel_dp->psr.sink_panel_replay_su_support)
+ goto unsupported;
+
+ if (intel_dsc_enabled_on_link(crtc_state) &&
+ intel_dp->psr.sink_panel_replay_dsc_support !=
+ INTEL_DP_PANEL_REPLAY_DSC_SELECTIVE_UPDATE) {
+ drm_dbg_kms(display->drm,
+ "Selective update with Panel Replay not enabled because it's not supported with DSC\n");
+ goto unsupported;
+ }
+ }
if (crtc_state->crc_enabled) {
drm_dbg_kms(display->drm,
@@ -1685,6 +1740,14 @@ _panel_replay_compute_config(struct intel_dp *intel_dp,
return false;
}
+ if (intel_dsc_enabled_on_link(crtc_state) &&
+ intel_dp->psr.sink_panel_replay_dsc_support ==
+ INTEL_DP_PANEL_REPLAY_DSC_NOT_SUPPORTED) {
+ drm_dbg_kms(display->drm,
+ "Panel Replay not enabled because it's not supported with DSC\n");
+ return false;
+ }
+
if (!intel_dp_is_edp(intel_dp))
return true;
@@ -1790,6 +1853,8 @@ void intel_psr_compute_config(struct intel_dp *intel_dp,
return;
}
+ /* Only used for state verification. */
+ crtc_state->panel_replay_dsc_support = intel_dp->psr.sink_panel_replay_dsc_support;
crtc_state->has_panel_replay = _panel_replay_compute_config(intel_dp,
crtc_state,
conn_state);
@@ -2991,6 +3056,20 @@ void intel_psr_pre_plane_update(struct intel_atomic_state *state,
}
}
+static void
+verify_panel_replay_dsc_state(const struct intel_crtc_state *crtc_state)
+{
+ struct intel_display *display = to_intel_display(crtc_state);
+
+ if (!crtc_state->has_panel_replay)
+ return;
+
+ drm_WARN_ON(display->drm,
+ intel_dsc_enabled_on_link(crtc_state) &&
+ crtc_state->panel_replay_dsc_support ==
+ INTEL_DP_PANEL_REPLAY_DSC_NOT_SUPPORTED);
+}
+
void intel_psr_post_plane_update(struct intel_atomic_state *state,
struct intel_crtc *crtc)
{
@@ -3002,6 +3081,8 @@ void intel_psr_post_plane_update(struct intel_atomic_state *state,
if (!crtc_state->has_psr)
return;
+ verify_panel_replay_dsc_state(crtc_state);
+
for_each_intel_encoder_mask_with_psr(state->base.dev, encoder,
crtc_state->uapi.encoder_mask) {
struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
@@ -4031,6 +4112,8 @@ static void intel_psr_sink_capability(struct intel_dp *intel_dp,
seq_printf(m, ", Panel Replay = %s", str_yes_no(psr->sink_panel_replay_support));
seq_printf(m, ", Panel Replay Selective Update = %s",
str_yes_no(psr->sink_panel_replay_su_support));
+ seq_printf(m, ", Panel Replay DSC support = %s",
+ panel_replay_dsc_support_str(psr->sink_panel_replay_dsc_support));
if (intel_dp->pr_dpcd[INTEL_PR_DPCD_INDEX(DP_PANEL_REPLAY_CAP_SUPPORT)] &
DP_PANEL_REPLAY_EARLY_TRANSPORT_SUPPORT)
seq_printf(m, " (Early Transport)");
--
2.50.1 (Apple Git-155)

View File

@ -0,0 +1,65 @@
From af5918335a6b77434c851c87d24e75eb7f93b8cb Mon Sep 17 00:00:00 2001
From: David Marlin <dmarlin@redhat.com>
Date: Wed, 15 Apr 2026 22:49:21 -0500
Subject: [PATCH] Bluetooth: SCO: Fix use-after-free in sco_recv_frame() due to
missing sock_hold
JIRA: https://issues.redhat.com/browse/RHEL-157827
commit 598dbba9919c5e36c54fe1709b557d64120cb94b
Author: Hyunwoo Kim <imv4bel@gmail.com>
Date: Fri Mar 13 05:26:16 2026 +0900
Bluetooth: SCO: Fix use-after-free in sco_recv_frame() due to missing sock_hold
sco_recv_frame() reads conn->sk under sco_conn_lock() but immediately
releases the lock without holding a reference to the socket. A concurrent
close() can free the socket between the lock release and the subsequent
sk->sk_state access, resulting in a use-after-free.
Other functions in the same file (sco_sock_timeout(), sco_conn_del())
correctly use sco_sock_hold() to safely hold a reference under the lock.
Fix by using sco_sock_hold() to take a reference before releasing the
lock, and adding sock_put() on all exit paths.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: Hyunwoo Kim <imv4bel@gmail.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: David Marlin <dmarlin@redhat.com>
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c
index 2b937df7a71f..6fc0914c74cb 100644
--- a/net/bluetooth/sco.c
+++ b/net/bluetooth/sco.c
@@ -401,7 +401,7 @@ static void sco_recv_frame(struct sco_conn *conn, struct sk_buff *skb)
struct sock *sk;
sco_conn_lock(conn);
- sk = conn->sk;
+ sk = sco_sock_hold(conn);
sco_conn_unlock(conn);
if (!sk)
@@ -410,11 +410,15 @@ static void sco_recv_frame(struct sco_conn *conn, struct sk_buff *skb)
BT_DBG("sk %p len %u", sk, skb->len);
if (sk->sk_state != BT_CONNECTED)
- goto drop;
+ goto drop_put;
- if (!sock_queue_rcv_skb(sk, skb))
+ if (!sock_queue_rcv_skb(sk, skb)) {
+ sock_put(sk);
return;
+ }
+drop_put:
+ sock_put(sk);
drop:
kfree_skb(skb);
}
--
2.50.1 (Apple Git-155)

View File

@ -0,0 +1,98 @@
From b53cdfa3715c656f739adda6465bc405c536f37b Mon Sep 17 00:00:00 2001
From: Vitaly Kuznetsov <vkuznets@redhat.com>
Date: Tue, 28 Apr 2026 14:00:04 +0200
Subject: [PATCH] scsi: storvsc: Handle PERSISTENT_RESERVE_IN truncation for
Hyper-V vFC
JIRA: https://redhat.atlassian.net/browse/RHEL-171460
commit 9cf351b289fb2be22491fa3964f99126db67aa08
Author: Li Tian <litian@redhat.com>
Date: Mon Apr 6 09:53:44 2026 +0800
scsi: storvsc: Handle PERSISTENT_RESERVE_IN truncation for Hyper-V vFC
The storvsc driver has become stricter in handling SRB status codes
returned by the Hyper-V host. When using Virtual Fibre Channel (vFC)
passthrough, the host may return SRB_STATUS_DATA_OVERRUN for
PERSISTENT_RESERVE_IN commands if the allocation length in the CDB does
not match the host's expected response size.
Currently, this status is treated as a fatal error, propagating
Host_status=0x07 [DID_ERROR] to the SCSI mid-layer. This causes
userspace storage utilities (such as sg_persist) to fail with transport
errors, even when the host has actually returned the requested
reservation data in the buffer.
Refactor the existing command-specific workarounds into a new helper
function, storvsc_host_mishandles_cmd(), and add PERSISTENT_RESERVE_IN
to the list of commands where SRB status errors should be suppressed for
vFC devices. This ensures that the SCSI mid-layer processes the returned
data buffer instead of terminating the command.
Signed-off-by: Li Tian <litian@redhat.com>
Reviewed-by: Long Li <longli@microsoft.com>
Reviewed-by: Laurence Oberman <loberman@redhat.com>
Link: https://patch.msgid.link/20260406015344.12566-1-litian@redhat.com
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index b47cda30e109..11e3aaae77be 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -1131,6 +1131,26 @@ static void storvsc_command_completion(struct storvsc_cmd_request *cmd_request,
kfree(payload);
}
+/*
+ * The current SCSI handling on the host side does not correctly handle:
+ * INQUIRY with page code 0x80, MODE_SENSE / MODE_SENSE_10 with cmd[2] == 0x1c,
+ * and (for FC) MAINTENANCE_IN / PERSISTENT_RESERVE_IN passthrough.
+ */
+static bool storvsc_host_mishandles_cmd(u8 opcode, struct hv_device *device)
+{
+ switch (opcode) {
+ case INQUIRY:
+ case MODE_SENSE:
+ case MODE_SENSE_10:
+ return true;
+ case MAINTENANCE_IN:
+ case PERSISTENT_RESERVE_IN:
+ return hv_dev_is_fc(device);
+ default:
+ return false;
+ }
+}
+
static void storvsc_on_io_completion(struct storvsc_device *stor_device,
struct vstor_packet *vstor_packet,
struct storvsc_cmd_request *request)
@@ -1141,22 +1161,12 @@ static void storvsc_on_io_completion(struct storvsc_device *stor_device,
stor_pkt = &request->vstor_packet;
/*
- * The current SCSI handling on the host side does
- * not correctly handle:
- * INQUIRY command with page code parameter set to 0x80
- * MODE_SENSE and MODE_SENSE_10 command with cmd[2] == 0x1c
- * MAINTENANCE_IN is not supported by HyperV FC passthrough
- *
* Setup srb and scsi status so this won't be fatal.
* We do this so we can distinguish truly fatal failues
* (srb status == 0x4) and off-line the device in that case.
*/
- if ((stor_pkt->vm_srb.cdb[0] == INQUIRY) ||
- (stor_pkt->vm_srb.cdb[0] == MODE_SENSE) ||
- (stor_pkt->vm_srb.cdb[0] == MODE_SENSE_10) ||
- (stor_pkt->vm_srb.cdb[0] == MAINTENANCE_IN &&
- hv_dev_is_fc(device))) {
+ if (storvsc_host_mishandles_cmd(stor_pkt->vm_srb.cdb[0], device)) {
vstor_packet->vm_srb.scsi_status = 0;
vstor_packet->vm_srb.srb_status = SRB_STATUS_SUCCESS;
}
--
2.50.1 (Apple Git-155)

View File

@ -0,0 +1,52 @@
From 288852ae095fabc060f4823784bec8cd5baf2edf Mon Sep 17 00:00:00 2001
From: Herbert Xu <herbert.xu@redhat.com>
Date: Thu, 30 Apr 2026 12:54:18 +0800
Subject: [PATCH] crypto: af-alg - fix NULL pointer dereference in scatterwalk
JIRA: https://redhat.atlassian.net/browse/RHEL-172216
Upstream Status: 62397b493e14107ae82d8b80938f293d95425bcb
commit 62397b493e14107ae82d8b80938f293d95425bcb
Author: Norbert Szetei <norbert@doyensec.com>
Date: Wed Mar 25 18:26:13 2026 +0100
crypto: af-alg - fix NULL pointer dereference in scatterwalk
The AF_ALG interface fails to unmark the end of a Scatter/Gather List (SGL)
when chaining a new af_alg_tsgl structure. If a sendmsg() fills an SGL
exactly to MAX_SGL_ENTS, the last entry is marked as the end. A subsequent
sendmsg() allocates a new SGL and chains it, but fails to clear the end
marker on the previous SGL's last data entry.
This causes the crypto scatterwalk to hit a premature end, returning NULL
on sg_next() and leading to a kernel panic during dereference.
Fix this by explicitly unmarking the end of the previous SGL when
performing sg_chain() in af_alg_alloc_tsgl().
Fixes: 8ff590903d5f ("crypto: algif_skcipher - User-space interface for skcipher operations")
Signed-off-by: Norbert Szetei <norbert@doyensec.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: Herbert Xu <herbert.xu@redhat.com>
diff --git a/crypto/af_alg.c b/crypto/af_alg.c
index 0da7c1ac778a..1594a2dd9222 100644
--- a/crypto/af_alg.c
+++ b/crypto/af_alg.c
@@ -623,8 +623,10 @@ static int af_alg_alloc_tsgl(struct sock *sk)
sg_init_table(sgl->sg, MAX_SGL_ENTS + 1);
sgl->cur = 0;
- if (sg)
+ if (sg) {
+ sg_unmark_end(sg + MAX_SGL_ENTS - 1);
sg_chain(sg, MAX_SGL_ENTS + 1, sgl->sg);
+ }
list_add_tail(&sgl->list, &ctx->tsgl_list);
}
--
2.50.1 (Apple Git-155)

View File

@ -0,0 +1,327 @@
From 290aaf22a335e76982159d1cb5eec8566628fa40 Mon Sep 17 00:00:00 2001
From: Herbert Xu <herbert.xu@redhat.com>
Date: Thu, 30 Apr 2026 20:52:06 +0800
Subject: [PATCH] crypto: algif_aead - Revert to operating out-of-place
JIRA: https://redhat.atlassian.net/browse/RHEL-172216
CVE: CVE-2026-31431
Upstream Status: a664bf3d603dc3bdcf9ae47cc21e0daec706d7a5
commit a664bf3d603dc3bdcf9ae47cc21e0daec706d7a5
Author: Herbert Xu <herbert@gondor.apana.org.au>
Date: Thu Mar 26 15:30:20 2026 +0900
crypto: algif_aead - Revert to operating out-of-place
This mostly reverts commit 72548b093ee3 except for the copying of
the associated data.
There is no benefit in operating in-place in algif_aead since the
source and destination come from different mappings. Get rid of
all the complexity added for in-place operation and just copy the
AD directly.
Fixes: 72548b093ee3 ("crypto: algif_aead - copy AAD from src to dst")
Reported-by: Taeyang Lee <0wn@theori.io>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: Herbert Xu <herbert.xu@redhat.com>
diff --git a/crypto/af_alg.c b/crypto/af_alg.c
index 1594a2dd9222..b2fe28992ebf 100644
--- a/crypto/af_alg.c
+++ b/crypto/af_alg.c
@@ -637,15 +637,13 @@ static int af_alg_alloc_tsgl(struct sock *sk)
/**
* af_alg_count_tsgl - Count number of TX SG entries
*
- * The counting starts from the beginning of the SGL to @bytes. If
- * an @offset is provided, the counting of the SG entries starts at the @offset.
+ * The counting starts from the beginning of the SGL to @bytes.
*
* @sk: socket of connection to user space
* @bytes: Count the number of SG entries holding given number of bytes.
- * @offset: Start the counting of SG entries from the given offset.
* Return: Number of TX SG entries found given the constraints
*/
-unsigned int af_alg_count_tsgl(struct sock *sk, size_t bytes, size_t offset)
+unsigned int af_alg_count_tsgl(struct sock *sk, size_t bytes)
{
const struct alg_sock *ask = alg_sk(sk);
const struct af_alg_ctx *ctx = ask->private;
@@ -660,25 +658,11 @@ unsigned int af_alg_count_tsgl(struct sock *sk, size_t bytes, size_t offset)
const struct scatterlist *sg = sgl->sg;
for (i = 0; i < sgl->cur; i++) {
- size_t bytes_count;
-
- /* Skip offset */
- if (offset >= sg[i].length) {
- offset -= sg[i].length;
- bytes -= sg[i].length;
- continue;
- }
-
- bytes_count = sg[i].length - offset;
-
- offset = 0;
sgl_count++;
-
- /* If we have seen requested number of bytes, stop */
- if (bytes_count >= bytes)
+ if (sg[i].length >= bytes)
return sgl_count;
- bytes -= bytes_count;
+ bytes -= sg[i].length;
}
}
@@ -690,19 +674,14 @@ EXPORT_SYMBOL_GPL(af_alg_count_tsgl);
* af_alg_pull_tsgl - Release the specified buffers from TX SGL
*
* If @dst is non-null, reassign the pages to @dst. The caller must release
- * the pages. If @dst_offset is given only reassign the pages to @dst starting
- * at the @dst_offset (byte). The caller must ensure that @dst is large
- * enough (e.g. by using af_alg_count_tsgl with the same offset).
+ * the pages.
*
* @sk: socket of connection to user space
* @used: Number of bytes to pull from TX SGL
* @dst: If non-NULL, buffer is reassigned to dst SGL instead of releasing. The
* caller must release the buffers in dst.
- * @dst_offset: Reassign the TX SGL from given offset. All buffers before
- * reaching the offset is released.
*/
-void af_alg_pull_tsgl(struct sock *sk, size_t used, struct scatterlist *dst,
- size_t dst_offset)
+void af_alg_pull_tsgl(struct sock *sk, size_t used, struct scatterlist *dst)
{
struct alg_sock *ask = alg_sk(sk);
struct af_alg_ctx *ctx = ask->private;
@@ -727,18 +706,10 @@ void af_alg_pull_tsgl(struct sock *sk, size_t used, struct scatterlist *dst,
* SG entries in dst.
*/
if (dst) {
- if (dst_offset >= plen) {
- /* discard page before offset */
- dst_offset -= plen;
- } else {
- /* reassign page to dst after offset */
- get_page(page);
- sg_set_page(dst + j, page,
- plen - dst_offset,
- sg[i].offset + dst_offset);
- dst_offset = 0;
- j++;
- }
+ /* reassign page to dst after offset */
+ get_page(page);
+ sg_set_page(dst + j, page, plen, sg[i].offset);
+ j++;
}
sg[i].length -= plen;
diff --git a/crypto/algif_aead.c b/crypto/algif_aead.c
index 7d58cbbce4af..dff71bd753a7 100644
--- a/crypto/algif_aead.c
+++ b/crypto/algif_aead.c
@@ -96,9 +96,8 @@ static int _aead_recvmsg(struct socket *sock, struct msghdr *msg,
struct aead_tfm *aeadc = pask->private;
struct crypto_aead *tfm = aeadc->aead;
struct crypto_sync_skcipher *null_tfm = aeadc->null_tfm;
- unsigned int i, as = crypto_aead_authsize(tfm);
+ unsigned int as = crypto_aead_authsize(tfm);
struct af_alg_async_req *areq;
- struct af_alg_tsgl *tsgl, *tmp;
struct scatterlist *rsgl_src, *tsgl_src = NULL;
int err = 0;
size_t used = 0; /* [in] TX bufs to be en/decrypted */
@@ -178,23 +177,24 @@ static int _aead_recvmsg(struct socket *sock, struct msghdr *msg,
outlen -= less;
}
+ /*
+ * Create a per request TX SGL for this request which tracks the
+ * SG entries from the global TX SGL.
+ */
processed = used + ctx->aead_assoclen;
- list_for_each_entry_safe(tsgl, tmp, &ctx->tsgl_list, list) {
- for (i = 0; i < tsgl->cur; i++) {
- struct scatterlist *process_sg = tsgl->sg + i;
-
- if (!(process_sg->length) || !sg_page(process_sg))
- continue;
- tsgl_src = process_sg;
- break;
- }
- if (tsgl_src)
- break;
- }
- if (processed && !tsgl_src) {
- err = -EFAULT;
+ areq->tsgl_entries = af_alg_count_tsgl(sk, processed);
+ if (!areq->tsgl_entries)
+ areq->tsgl_entries = 1;
+ areq->tsgl = sock_kmalloc(sk, array_size(sizeof(*areq->tsgl),
+ areq->tsgl_entries),
+ GFP_KERNEL);
+ if (!areq->tsgl) {
+ err = -ENOMEM;
goto free;
}
+ sg_init_table(areq->tsgl, areq->tsgl_entries);
+ af_alg_pull_tsgl(sk, processed, areq->tsgl);
+ tsgl_src = areq->tsgl;
/*
* Copy of AAD from source to destination
@@ -203,83 +203,18 @@ static int _aead_recvmsg(struct socket *sock, struct msghdr *msg,
* when user space uses an in-place cipher operation, the kernel
* will copy the data as it does not see whether such in-place operation
* is initiated.
- *
- * To ensure efficiency, the following implementation ensure that the
- * ciphers are invoked to perform a crypto operation in-place. This
- * is achieved by memory management specified as follows.
*/
/* Use the RX SGL as source (and destination) for crypto op. */
rsgl_src = areq->first_rsgl.sgl.sgt.sgl;
- if (ctx->enc) {
- /*
- * Encryption operation - The in-place cipher operation is
- * achieved by the following operation:
- *
- * TX SGL: AAD || PT
- * | |
- * | copy |
- * v v
- * RX SGL: AAD || PT || Tag
- */
- err = crypto_aead_copy_sgl(null_tfm, tsgl_src,
- areq->first_rsgl.sgl.sgt.sgl,
- processed);
- if (err)
- goto free;
- af_alg_pull_tsgl(sk, processed, NULL, 0);
- } else {
- /*
- * Decryption operation - To achieve an in-place cipher
- * operation, the following SGL structure is used:
- *
- * TX SGL: AAD || CT || Tag
- * | | ^
- * | copy | | Create SGL link.
- * v v |
- * RX SGL: AAD || CT ----+
- */
-
- /* Copy AAD || CT to RX SGL buffer for in-place operation. */
- err = crypto_aead_copy_sgl(null_tfm, tsgl_src,
- areq->first_rsgl.sgl.sgt.sgl,
- outlen);
- if (err)
- goto free;
-
- /* Create TX SGL for tag and chain it to RX SGL. */
- areq->tsgl_entries = af_alg_count_tsgl(sk, processed,
- processed - as);
- if (!areq->tsgl_entries)
- areq->tsgl_entries = 1;
- areq->tsgl = sock_kmalloc(sk, array_size(sizeof(*areq->tsgl),
- areq->tsgl_entries),
- GFP_KERNEL);
- if (!areq->tsgl) {
- err = -ENOMEM;
- goto free;
- }
- sg_init_table(areq->tsgl, areq->tsgl_entries);
-
- /* Release TX SGL, except for tag data and reassign tag data. */
- af_alg_pull_tsgl(sk, processed, areq->tsgl, processed - as);
-
- /* chain the areq TX SGL holding the tag with RX SGL */
- if (usedpages) {
- /* RX SGL present */
- struct af_alg_sgl *sgl_prev = &areq->last_rsgl->sgl;
- struct scatterlist *sg = sgl_prev->sgt.sgl;
-
- sg_unmark_end(sg + sgl_prev->sgt.nents - 1);
- sg_chain(sg, sgl_prev->sgt.nents + 1, areq->tsgl);
- } else
- /* no RX SGL present (e.g. authentication only) */
- rsgl_src = areq->tsgl;
- }
+ err = crypto_aead_copy_sgl(null_tfm, tsgl_src, rsgl_src,
+ ctx->aead_assoclen);
+ if (err)
+ goto free;
/* Initialize the crypto operation */
- aead_request_set_crypt(&areq->cra_u.aead_req, rsgl_src,
+ aead_request_set_crypt(&areq->cra_u.aead_req, tsgl_src,
areq->first_rsgl.sgl.sgt.sgl, used, ctx->iv);
aead_request_set_ad(&areq->cra_u.aead_req, ctx->aead_assoclen);
aead_request_set_tfm(&areq->cra_u.aead_req, tfm);
@@ -514,7 +449,7 @@ static void aead_sock_destruct(struct sock *sk)
struct crypto_aead *tfm = aeadc->aead;
unsigned int ivlen = crypto_aead_ivsize(tfm);
- af_alg_pull_tsgl(sk, ctx->used, NULL, 0);
+ af_alg_pull_tsgl(sk, ctx->used, NULL);
sock_kzfree_s(sk, ctx->iv, ivlen);
sock_kfree_s(sk, ctx, ctx->len);
af_alg_release_parent(sk);
diff --git a/crypto/algif_skcipher.c b/crypto/algif_skcipher.c
index 125d395c5e00..82735e51be10 100644
--- a/crypto/algif_skcipher.c
+++ b/crypto/algif_skcipher.c
@@ -138,7 +138,7 @@ static int _skcipher_recvmsg(struct socket *sock, struct msghdr *msg,
* Create a per request TX SGL for this request which tracks the
* SG entries from the global TX SGL.
*/
- areq->tsgl_entries = af_alg_count_tsgl(sk, len, 0);
+ areq->tsgl_entries = af_alg_count_tsgl(sk, len);
if (!areq->tsgl_entries)
areq->tsgl_entries = 1;
areq->tsgl = sock_kmalloc(sk, array_size(sizeof(*areq->tsgl),
@@ -149,7 +149,7 @@ static int _skcipher_recvmsg(struct socket *sock, struct msghdr *msg,
goto free;
}
sg_init_table(areq->tsgl, areq->tsgl_entries);
- af_alg_pull_tsgl(sk, len, areq->tsgl, 0);
+ af_alg_pull_tsgl(sk, len, areq->tsgl);
/* Initialize the crypto operation */
skcipher_request_set_tfm(&areq->cra_u.skcipher_req, tfm);
@@ -363,7 +363,7 @@ static void skcipher_sock_destruct(struct sock *sk)
struct alg_sock *pask = alg_sk(psk);
struct crypto_skcipher *tfm = pask->private;
- af_alg_pull_tsgl(sk, ctx->used, NULL, 0);
+ af_alg_pull_tsgl(sk, ctx->used, NULL);
sock_kzfree_s(sk, ctx->iv, crypto_skcipher_ivsize(tfm));
if (ctx->state)
sock_kzfree_s(sk, ctx->state, crypto_skcipher_statesize(tfm));
diff --git a/include/crypto/if_alg.h b/include/crypto/if_alg.h
index f7b3b93f3a49..b32d1ef827e7 100644
--- a/include/crypto/if_alg.h
+++ b/include/crypto/if_alg.h
@@ -228,9 +228,8 @@ static inline bool af_alg_readable(struct sock *sk)
return PAGE_SIZE <= af_alg_rcvbuf(sk);
}
-unsigned int af_alg_count_tsgl(struct sock *sk, size_t bytes, size_t offset);
-void af_alg_pull_tsgl(struct sock *sk, size_t used, struct scatterlist *dst,
- size_t dst_offset);
+unsigned int af_alg_count_tsgl(struct sock *sk, size_t bytes);
+void af_alg_pull_tsgl(struct sock *sk, size_t used, struct scatterlist *dst);
void af_alg_wmem_wakeup(struct sock *sk);
int af_alg_wait_for_data(struct sock *sk, unsigned flags, unsigned min);
int af_alg_sendmsg(struct socket *sock, struct msghdr *msg, size_t size,
--
2.50.1 (Apple Git-155)

View File

@ -0,0 +1,73 @@
From ea7f6a374f53f1ecba89d146c138bf71df660ae9 Mon Sep 17 00:00:00 2001
From: Herbert Xu <herbert.xu@redhat.com>
Date: Fri, 1 May 2026 21:43:21 +0800
Subject: [PATCH] crypto: af_alg - limit RX SG extraction by receive buffer
budget
JIRA: https://redhat.atlassian.net/browse/RHEL-172216
CVE: CVE-2026-31677
Upstream Status: 8eceab19eba9dcbfd2a0daec72e1bf48aa100170
commit 8eceab19eba9dcbfd2a0daec72e1bf48aa100170
Author: Douya Le <ldy3087146292@gmail.com>
Date: Thu Apr 2 23:34:55 2026 +0800
crypto: af_alg - limit RX SG extraction by receive buffer budget
Make af_alg_get_rsgl() limit each RX scatterlist extraction to the
remaining receive buffer budget.
af_alg_get_rsgl() currently uses af_alg_readable() only as a gate
before extracting data into the RX scatterlist. Limit each extraction
to the remaining af_alg_rcvbuf(sk) budget so that receive-side
accounting matches the amount of data attached to the request.
If skcipher cannot obtain enough RX space for at least one chunk while
more data remains to be processed, reject the recvmsg call instead of
rounding the request length down to zero.
Fixes: e870456d8e7c8d57c059ea479b5aadbb55ff4c3a ("crypto: algif_skcipher - overhaul memory management")
Reported-by: Yifan Wu <yifanwucs@gmail.com>
Reported-by: Juefei Pu <tomapufckgml@gmail.com>
Co-developed-by: Yuan Tan <yuantan098@gmail.com>
Signed-off-by: Yuan Tan <yuantan098@gmail.com>
Suggested-by: Xin Liu <bird@lzu.edu.cn>
Signed-off-by: Douya Le <ldy3087146292@gmail.com>
Signed-off-by: Ren Wei <n05ec@lzu.edu.cn>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: Herbert Xu <herbert.xu@redhat.com>
diff --git a/crypto/af_alg.c b/crypto/af_alg.c
index b2fe28992ebf..fbb669c9478c 100644
--- a/crypto/af_alg.c
+++ b/crypto/af_alg.c
@@ -1222,6 +1222,8 @@ int af_alg_get_rsgl(struct sock *sk, struct msghdr *msg, int flags,
seglen = min_t(size_t, (maxsize - len),
msg_data_left(msg));
+ /* Never pin more pages than the remaining RX accounting budget. */
+ seglen = min_t(size_t, seglen, af_alg_rcvbuf(sk));
if (list_empty(&areq->rsgl_list)) {
rsgl = &areq->first_rsgl;
diff --git a/crypto/algif_skcipher.c b/crypto/algif_skcipher.c
index 82735e51be10..ba0a17fd95ac 100644
--- a/crypto/algif_skcipher.c
+++ b/crypto/algif_skcipher.c
@@ -130,6 +130,11 @@ static int _skcipher_recvmsg(struct socket *sock, struct msghdr *msg,
* full block size buffers.
*/
if (ctx->more || len < ctx->used) {
+ if (len < bs) {
+ err = -EINVAL;
+ goto free;
+ }
+
len -= len % bs;
cflags |= CRYPTO_SKCIPHER_REQ_NOTFINAL;
}
--
2.50.1 (Apple Git-155)

View File

@ -0,0 +1,49 @@
From 1921edf676419a881548b4779c4556dc936b10f2 Mon Sep 17 00:00:00 2001
From: Herbert Xu <herbert.xu@redhat.com>
Date: Thu, 30 Apr 2026 20:10:09 +0800
Subject: [PATCH] crypto: af_alg - Fix page reassignment overflow in
af_alg_pull_tsgl
JIRA: https://redhat.atlassian.net/browse/RHEL-172216
Upstream Status: 31d00156e50ecad37f2cb6cbf04aaa9a260505ef
commit 31d00156e50ecad37f2cb6cbf04aaa9a260505ef
Author: Herbert Xu <herbert@gondor.apana.org.au>
Date: Sat Apr 4 08:29:58 2026 +0800
crypto: af_alg - Fix page reassignment overflow in af_alg_pull_tsgl
When page reassignment was added to af_alg_pull_tsgl the original
loop wasn't updated so it may try to reassign one more page than
necessary.
Add the check to the reassignment so that this does not happen.
Also update the comment which still refers to the obsolete offset
argument.
Reported-by: syzbot+d23888375c2737c17ba5@syzkaller.appspotmail.com
Fixes: e870456d8e7c ("crypto: algif_skcipher - overhaul memory management")
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: Herbert Xu <herbert.xu@redhat.com>
diff --git a/crypto/af_alg.c b/crypto/af_alg.c
index fbb669c9478c..4c94448e4659 100644
--- a/crypto/af_alg.c
+++ b/crypto/af_alg.c
@@ -705,8 +705,8 @@ void af_alg_pull_tsgl(struct sock *sk, size_t used, struct scatterlist *dst)
* Assumption: caller created af_alg_count_tsgl(len)
* SG entries in dst.
*/
- if (dst) {
- /* reassign page to dst after offset */
+ if (dst && plen) {
+ /* reassign page to dst */
get_page(page);
sg_set_page(dst + j, page, plen, sg[i].offset);
j++;
--
2.50.1 (Apple Git-155)

View File

@ -0,0 +1,58 @@
From 501c9d9404330aa57a3efe128e0e16dc98f4475f Mon Sep 17 00:00:00 2001
From: Herbert Xu <herbert.xu@redhat.com>
Date: Fri, 1 May 2026 21:43:58 +0800
Subject: [PATCH] crypto: authencesn - reject too-short AAD (assoclen<8) to
match ESP/ESN spec
JIRA: https://redhat.atlassian.net/browse/RHEL-172216
CVE: CVE-2026-23060
Upstream Status: 2397e9264676be7794f8f7f1e9763d90bd3c7335
commit 2397e9264676be7794f8f7f1e9763d90bd3c7335
Author: Taeyang Lee <0wn@theori.io>
Date: Fri Jan 16 16:03:58 2026 +0900
crypto: authencesn - reject too-short AAD (assoclen<8) to match ESP/ESN spec
authencesn assumes an ESP/ESN-formatted AAD. When assoclen is shorter than
the minimum expected length, crypto_authenc_esn_decrypt() can advance past
the end of the destination scatterlist and trigger a NULL pointer dereference
in scatterwalk_map_and_copy(), leading to a kernel panic (DoS).
Add a minimum AAD length check to fail fast on invalid inputs.
Fixes: 104880a6b470 ("crypto: authencesn - Convert to new AEAD interface")
Reported-By: Taeyang Lee <0wn@theori.io>
Signed-off-by: Taeyang Lee <0wn@theori.io>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: Herbert Xu <herbert.xu@redhat.com>
diff --git a/crypto/authencesn.c b/crypto/authencesn.c
index 2cc933e2f790..e08032e80f18 100644
--- a/crypto/authencesn.c
+++ b/crypto/authencesn.c
@@ -185,6 +185,9 @@ static int crypto_authenc_esn_encrypt(struct aead_request *req)
struct scatterlist *src, *dst;
int err;
+ if (assoclen < 8)
+ return -EINVAL;
+
sg_init_table(areq_ctx->src, 2);
src = scatterwalk_ffwd(areq_ctx->src, req->src, assoclen);
dst = src;
@@ -275,6 +278,9 @@ static int crypto_authenc_esn_decrypt(struct aead_request *req)
u32 tmp[2];
int err;
+ if (assoclen < 8)
+ return -EINVAL;
+
cryptlen -= authsize;
if (req->src != dst) {
--
2.50.1 (Apple Git-155)

View File

@ -0,0 +1,172 @@
From 1508578044aa2d26ae287927419505ad8c1ef8f1 Mon Sep 17 00:00:00 2001
From: Herbert Xu <herbert.xu@redhat.com>
Date: Thu, 30 Apr 2026 20:16:25 +0800
Subject: [PATCH] crypto: authencesn - Do not place hiseq at end of dst for
out-of-place decryption
JIRA: https://redhat.atlassian.net/browse/RHEL-172216
CVE: CVE-2026-31431
Upstream Status: e02494114ebf7c8b42777c6cd6982f113bfdbec7
commit e02494114ebf7c8b42777c6cd6982f113bfdbec7
Author: Herbert Xu <herbert@gondor.apana.org.au>
Date: Fri Mar 27 15:04:17 2026 +0900
crypto: authencesn - Do not place hiseq at end of dst for out-of-place decryption
When decrypting data that is not in-place (src != dst), there is
no need to save the high-order sequence bits in dst as it could
simply be re-copied from the source.
However, the data to be hashed need to be rearranged accordingly.
Reported-by: Taeyang Lee <0wn@theori.io>
Fixes: 104880a6b470 ("crypto: authencesn - Convert to new AEAD interface")
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Thanks,
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: Herbert Xu <herbert.xu@redhat.com>
diff --git a/crypto/authencesn.c b/crypto/authencesn.c
index e08032e80f18..b262e7e3f8d7 100644
--- a/crypto/authencesn.c
+++ b/crypto/authencesn.c
@@ -158,7 +158,10 @@ static void crypto_authenc_esn_encrypt_done(void *data, int err)
authenc_esn_request_complete(areq, err);
}
-static int crypto_authenc_esn_copy(struct aead_request *req, unsigned int len)
+static int crypto_authenc_esn_copy_sg(struct aead_request *req,
+ struct scatterlist *src,
+ struct scatterlist *dst,
+ unsigned int len)
{
struct crypto_aead *authenc_esn = crypto_aead_reqtfm(req);
struct crypto_authenc_esn_ctx *ctx = crypto_aead_ctx(authenc_esn);
@@ -167,11 +170,16 @@ static int crypto_authenc_esn_copy(struct aead_request *req, unsigned int len)
skcipher_request_set_sync_tfm(skreq, ctx->null);
skcipher_request_set_callback(skreq, aead_request_flags(req),
NULL, NULL);
- skcipher_request_set_crypt(skreq, req->src, req->dst, len, NULL);
+ skcipher_request_set_crypt(skreq, src, dst, len, NULL);
return crypto_skcipher_encrypt(skreq);
}
+static int crypto_authenc_esn_copy(struct aead_request *req, unsigned int len)
+{
+ return crypto_authenc_esn_copy_sg(req, req->src, req->dst, len);
+}
+
static int crypto_authenc_esn_encrypt(struct aead_request *req)
{
struct crypto_aead *authenc_esn = crypto_aead_reqtfm(req);
@@ -226,30 +234,39 @@ static int crypto_authenc_esn_decrypt_tail(struct aead_request *req,
u8 *ohash = areq_ctx->tail;
unsigned int cryptlen = req->cryptlen - authsize;
unsigned int assoclen = req->assoclen;
+ struct scatterlist *src = req->src;
struct scatterlist *dst = req->dst;
u8 *ihash = ohash + crypto_ahash_digestsize(auth);
u32 tmp[2];
+ int err;
if (!authsize)
goto decrypt;
- /* Move high-order bits of sequence number back. */
- scatterwalk_map_and_copy(tmp, dst, 4, 4, 0);
- scatterwalk_map_and_copy(tmp + 1, dst, assoclen + cryptlen, 4, 0);
- scatterwalk_map_and_copy(tmp, dst, 0, 8, 1);
+ if (src == dst) {
+ /* Move high-order bits of sequence number back. */
+ scatterwalk_map_and_copy(tmp, dst, 4, 4, 0);
+ scatterwalk_map_and_copy(tmp + 1, dst, assoclen + cryptlen, 4, 0);
+ scatterwalk_map_and_copy(tmp, dst, 0, 8, 1);
+ } else {
+ err = crypto_authenc_esn_copy(req, assoclen);
+ if (err)
+ return err;
+ }
if (crypto_memneq(ihash, ohash, authsize))
return -EBADMSG;
decrypt:
- sg_init_table(areq_ctx->dst, 2);
+ if (src != dst)
+ src = scatterwalk_ffwd(areq_ctx->src, src, assoclen);
dst = scatterwalk_ffwd(areq_ctx->dst, dst, assoclen);
skcipher_request_set_tfm(skreq, ctx->enc);
skcipher_request_set_callback(skreq, flags,
req->base.complete, req->base.data);
- skcipher_request_set_crypt(skreq, dst, dst, cryptlen, req->iv);
+ skcipher_request_set_crypt(skreq, src, dst, cryptlen, req->iv);
return crypto_skcipher_decrypt(skreq);
}
@@ -274,6 +291,7 @@ static int crypto_authenc_esn_decrypt(struct aead_request *req)
unsigned int assoclen = req->assoclen;
unsigned int cryptlen = req->cryptlen;
u8 *ihash = ohash + crypto_ahash_digestsize(auth);
+ struct scatterlist *src = req->src;
struct scatterlist *dst = req->dst;
u32 tmp[2];
int err;
@@ -281,27 +299,31 @@ static int crypto_authenc_esn_decrypt(struct aead_request *req)
if (assoclen < 8)
return -EINVAL;
- cryptlen -= authsize;
-
- if (req->src != dst) {
- err = crypto_authenc_esn_copy(req, assoclen + cryptlen);
- if (err)
- return err;
- }
+ if (!authsize)
+ goto tail;
+ cryptlen -= authsize;
scatterwalk_map_and_copy(ihash, req->src, assoclen + cryptlen,
authsize, 0);
- if (!authsize)
- goto tail;
-
/* Move high-order bits of sequence number to the end. */
- scatterwalk_map_and_copy(tmp, dst, 0, 8, 0);
- scatterwalk_map_and_copy(tmp, dst, 4, 4, 1);
- scatterwalk_map_and_copy(tmp + 1, dst, assoclen + cryptlen, 4, 1);
-
- sg_init_table(areq_ctx->dst, 2);
- dst = scatterwalk_ffwd(areq_ctx->dst, dst, 4);
+ scatterwalk_map_and_copy(tmp, src, 0, 8, 0);
+ if (src == dst) {
+ scatterwalk_map_and_copy(tmp, dst, 4, 4, 1);
+ scatterwalk_map_and_copy(tmp + 1, dst, assoclen + cryptlen, 4, 1);
+ dst = scatterwalk_ffwd(areq_ctx->dst, dst, 4);
+ } else {
+ scatterwalk_map_and_copy(tmp, dst, 0, 4, 1);
+ scatterwalk_map_and_copy(tmp + 1, dst, assoclen + cryptlen - 4, 4, 1);
+
+ src = scatterwalk_ffwd(areq_ctx->src, src, 8);
+ dst = scatterwalk_ffwd(areq_ctx->dst, dst, 4);
+ err = crypto_authenc_esn_copy_sg(req, src, dst,
+ assoclen + cryptlen - 8);
+ if (err)
+ return err;
+ dst = req->dst;
+ }
ahash_request_set_tfm(ahreq, auth);
ahash_request_set_crypt(ahreq, dst, ohash, assoclen + cryptlen);
--
2.50.1 (Apple Git-155)

View File

@ -0,0 +1,45 @@
From dadc0c1bbccad48022e400debc3341597a0f2cf5 Mon Sep 17 00:00:00 2001
From: Herbert Xu <herbert.xu@redhat.com>
Date: Thu, 30 Apr 2026 19:56:24 +0800
Subject: [PATCH] crypto: authencesn - Fix src offset when decrypting in-place
JIRA: https://redhat.atlassian.net/browse/RHEL-172216
Upstream Status: 1f48ad3b19a9dfc947868edda0bb8e48e5b5a8fa
commit 1f48ad3b19a9dfc947868edda0bb8e48e5b5a8fa
Author: Herbert Xu <herbert@gondor.apana.org.au>
Date: Wed Apr 15 07:39:06 2026 +0800
crypto: authencesn - Fix src offset when decrypting in-place
The src SG list offset wasn't set properly when decrypting in-place,
fix it.
Reported-by: Wolfgang Walter <linux@stwm.de>
Fixes: e02494114ebf ("crypto: authencesn - Do not place hiseq at end of dst for out-of-place decryption")
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: Herbert Xu <herbert.xu@redhat.com>
diff --git a/crypto/authencesn.c b/crypto/authencesn.c
index b262e7e3f8d7..d96da934674e 100644
--- a/crypto/authencesn.c
+++ b/crypto/authencesn.c
@@ -259,9 +259,11 @@ static int crypto_authenc_esn_decrypt_tail(struct aead_request *req,
decrypt:
- if (src != dst)
- src = scatterwalk_ffwd(areq_ctx->src, src, assoclen);
dst = scatterwalk_ffwd(areq_ctx->dst, dst, assoclen);
+ if (req->src == req->dst)
+ src = dst;
+ else
+ src = scatterwalk_ffwd(areq_ctx->src, src, assoclen);
skcipher_request_set_tfm(skreq, ctx->enc);
skcipher_request_set_callback(skreq, flags,
--
2.50.1 (Apple Git-155)

View File

@ -0,0 +1,70 @@
From 027fb22445c4faad4693db4c096b0674fe09f712 Mon Sep 17 00:00:00 2001
From: Herbert Xu <herbert.xu@redhat.com>
Date: Thu, 30 Apr 2026 20:02:19 +0800
Subject: [PATCH] crypto: authencesn - reject short ahash digests during
instance creation
JIRA: https://redhat.atlassian.net/browse/RHEL-172216
Upstream Status: cryptodev
commit 5db6ef9847717329f12c5ea8aba7e9f588a980c0
Author: Yucheng Lu <kanolyc@gmail.com>
Date: Wed Apr 22 21:45:04 2026 +0800
crypto: authencesn - reject short ahash digests during instance creation
authencesn requires either a zero authsize or an authsize of at least
4 bytes because the ESN encrypt/decrypt paths always move 4 bytes of
high-order sequence number data at the end of the authenticated data.
While crypto_authenc_esn_setauthsize() already rejects explicit
non-zero authsizes in the range 1..3, crypto_authenc_esn_create()
still copied auth->digestsize into inst->alg.maxauthsize without
validating it. The AEAD core then initialized the tfm's default
authsize from that value.
As a result, selecting an ahash with digest size 1..3, such as
cbcmac(cipher_null), exposed authencesn instances whose default
authsize was invalid even though setauthsize() would have rejected the
same value. AF_ALG could then trigger the ESN tail handling with a
too-short tag and hit an out-of-bounds access.
Reject authencesn instances whose ahash digest size is in the invalid
non-zero range 1..3 so that no tfm can inherit an unsupported default
authsize.
Fixes: f15f05b0a5de ("crypto: ccm - switch to separate cbcmac driver")
Cc: stable@kernel.org
Reported-by: Yifan Wu <yifanwucs@gmail.com>
Reported-by: Juefei Pu <tomapufckgml@gmail.com>
Co-developed-by: Yuan Tan <yuantan098@gmail.com>
Signed-off-by: Yuan Tan <yuantan098@gmail.com>
Suggested-by: Xin Liu <bird@lzu.edu.cn>
Tested-by: Yuhang Zheng <z1652074432@gmail.com>
Reviewed-by: Eric Biggers <ebiggers@kernel.org>
Signed-off-by: Yucheng Lu <kanolyc@gmail.com>
Signed-off-by: Ren Wei <n05ec@lzu.edu.cn>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: Herbert Xu <herbert.xu@redhat.com>
diff --git a/crypto/authencesn.c b/crypto/authencesn.c
index d96da934674e..8b94a34c6ab4 100644
--- a/crypto/authencesn.c
+++ b/crypto/authencesn.c
@@ -434,6 +434,11 @@ static int crypto_authenc_esn_create(struct crypto_template *tmpl,
auth = crypto_spawn_ahash_alg(&ctx->auth);
auth_base = &auth->base;
+ if (auth->digestsize > 0 && auth->digestsize < 4) {
+ err = -EINVAL;
+ goto err_free_inst;
+ }
+
err = crypto_grab_skcipher(&ctx->enc, aead_crypto_instance(inst),
crypto_attr_alg_name(tb[2]), 0, mask);
if (err)
--
2.50.1 (Apple Git-155)

View File

@ -0,0 +1,42 @@
From 51c927390f506ab91a571fff14994406e8a43fb4 Mon Sep 17 00:00:00 2001
From: Herbert Xu <herbert.xu@redhat.com>
Date: Fri, 1 May 2026 21:45:28 +0800
Subject: [PATCH] crypto: algif_aead - Fix minimum RX size check for decryption
JIRA: https://redhat.atlassian.net/browse/RHEL-172216
Upstream Status: 3d14bd48e3a77091cbce637a12c2ae31b4a1687c
commit 3d14bd48e3a77091cbce637a12c2ae31b4a1687c
Author: Herbert Xu <herbert@gondor.apana.org.au>
Date: Sun Apr 12 13:32:21 2026 +0800
crypto: algif_aead - Fix minimum RX size check for decryption
The check for the minimum receive buffer size did not take the
tag size into account during decryption. Fix this by adding the
required extra length.
Reported-by: syzbot+aa11561819dc42ebbc7c@syzkaller.appspotmail.com
Reported-by: Daniel Pouzzner <douzzer@mega.nu>
Fixes: d887c52d6ae4 ("crypto: algif_aead - overhaul memory management")
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: Herbert Xu <herbert.xu@redhat.com>
diff --git a/crypto/algif_aead.c b/crypto/algif_aead.c
index dff71bd753a7..93a7cb4f269c 100644
--- a/crypto/algif_aead.c
+++ b/crypto/algif_aead.c
@@ -169,7 +169,7 @@ static int _aead_recvmsg(struct socket *sock, struct msghdr *msg,
if (usedpages < outlen) {
size_t less = outlen - usedpages;
- if (used < less) {
+ if (used < less + (ctx->enc ? 0 : as)) {
err = -EINVAL;
goto free;
}
--
2.50.1 (Apple Git-155)

View File

@ -0,0 +1,82 @@
From 5ee3f090629291d2a9c229c0371b6410cd480826 Mon Sep 17 00:00:00 2001
From: Herbert Xu <herbert.xu@redhat.com>
Date: Thu, 30 Apr 2026 20:03:29 +0800
Subject: [PATCH] crypto: algif_aead - snapshot IV for async AEAD requests
JIRA: https://redhat.atlassian.net/browse/RHEL-172216
Upstream Status: 5aa58c3a572b3e3b6c786953339f7978b845cc52
commit 5aa58c3a572b3e3b6c786953339f7978b845cc52
Author: Douya Le <ldy3087146292@gmail.com>
Date: Sun Apr 19 16:52:59 2026 +0800
crypto: algif_aead - snapshot IV for async AEAD requests
AF_ALG AEAD AIO requests currently use the socket-wide IV buffer during
request processing. For async requests, later socket activity can
update that shared state before the original request has fully
completed, which can lead to inconsistent IV handling.
Snapshot the IV into per-request storage when preparing the AEAD
request, so in-flight operations no longer depend on mutable socket
state.
Fixes: d887c52d6ae4 ("crypto: algif_aead - overhaul memory management")
Cc: stable@kernel.org
Reported-by: Yuan Tan <yuantan098@gmail.com>
Reported-by: Yifan Wu <yifanwucs@gmail.com>
Reported-by: Juefei Pu <tomapufckgml@gmail.com>
Reported-by: Xin Liu <bird@lzu.edu.cn>
Co-developed-by: Luxing Yin <tr0jan@lzu.edu.cn>
Signed-off-by: Luxing Yin <tr0jan@lzu.edu.cn>
Tested-by: Yucheng Lu <kanolyc@gmail.com>
Signed-off-by: Douya Le <ldy3087146292@gmail.com>
Signed-off-by: Ren Wei <n05ec@lzu.edu.cn>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: Herbert Xu <herbert.xu@redhat.com>
diff --git a/crypto/algif_aead.c b/crypto/algif_aead.c
index 93a7cb4f269c..fcf86e5c6494 100644
--- a/crypto/algif_aead.c
+++ b/crypto/algif_aead.c
@@ -97,8 +97,10 @@ static int _aead_recvmsg(struct socket *sock, struct msghdr *msg,
struct crypto_aead *tfm = aeadc->aead;
struct crypto_sync_skcipher *null_tfm = aeadc->null_tfm;
unsigned int as = crypto_aead_authsize(tfm);
+ unsigned int ivsize = crypto_aead_ivsize(tfm);
struct af_alg_async_req *areq;
struct scatterlist *rsgl_src, *tsgl_src = NULL;
+ void *iv;
int err = 0;
size_t used = 0; /* [in] TX bufs to be en/decrypted */
size_t outlen = 0; /* [out] RX bufs produced by kernel */
@@ -150,10 +152,14 @@ static int _aead_recvmsg(struct socket *sock, struct msghdr *msg,
/* Allocate cipher request for current operation. */
areq = af_alg_alloc_areq(sk, sizeof(struct af_alg_async_req) +
- crypto_aead_reqsize(tfm));
+ crypto_aead_reqsize(tfm) + ivsize);
if (IS_ERR(areq))
return PTR_ERR(areq);
+ iv = (u8 *)aead_request_ctx(&areq->cra_u.aead_req) +
+ crypto_aead_reqsize(tfm);
+ memcpy(iv, ctx->iv, ivsize);
+
/* convert iovecs of output buffers into RX SGL */
err = af_alg_get_rsgl(sk, msg, flags, areq, outlen, &usedpages);
if (err)
@@ -215,7 +221,7 @@ static int _aead_recvmsg(struct socket *sock, struct msghdr *msg,
/* Initialize the crypto operation */
aead_request_set_crypt(&areq->cra_u.aead_req, tsgl_src,
- areq->first_rsgl.sgl.sgt.sgl, used, ctx->iv);
+ areq->first_rsgl.sgl.sgt.sgl, used, iv);
aead_request_set_ad(&areq->cra_u.aead_req, ctx->aead_assoclen);
aead_request_set_tfm(&areq->cra_u.aead_req, tfm);
--
2.50.1 (Apple Git-155)

View File

@ -0,0 +1,108 @@
From fec7c33519761c90689c4e41f169885a4dc6e729 Mon Sep 17 00:00:00 2001
From: CKI Backport Bot <cki-ci-bot+cki-gitlab-backport-bot@redhat.com>
Date: Thu, 7 May 2026 19:48:51 +0000
Subject: [PATCH] xfrm: esp: avoid in-place decrypt on shared skb frags
JIRA: https://redhat.atlassian.net/browse/RHEL-174522
CVE: CVE-2026-43284
commit f4c50a4034e62ab75f1d5cdd191dd5f9c77fdff4
Author: Kuan-Ting Chen <h3xrabbit@gmail.com>
Date: Mon May 4 23:27:12 2026 +0800
xfrm: esp: avoid in-place decrypt on shared skb frags
MSG_SPLICE_PAGES can attach pages from a pipe directly to an skb. TCP
marks such skbs with SKBFL_SHARED_FRAG after skb_splice_from_iter(),
so later paths that may modify packet data can first make a private
copy. The IPv4/IPv6 datagram append paths did not set this flag when
splicing pages into UDP skbs.
That leaves an ESP-in-UDP packet made from shared pipe pages looking
like an ordinary uncloned nonlinear skb. ESP input then takes the no-COW
fast path for uncloned skbs without a frag_list and decrypts in place
over data that is not owned privately by the skb.
Mark IPv4/IPv6 datagram splice frags with SKBFL_SHARED_FRAG, matching
TCP. Also make ESP input fall back to skb_cow_data() when the flag is
present, so ESP does not decrypt externally backed frags in place.
Private nonlinear skb frags still use the existing fast path.
This intentionally does not change ESP output. In esp_output_head(),
the path that appends the ESP trailer to existing skb tailroom without
calling skb_cow_data() is not reachable for nonlinear skbs:
skb_tailroom() returns zero when skb->data_len is nonzero, while ESP
tailen is positive. Thus ESP output will either use the separate
destination-frag path or fall back to skb_cow_data().
Fixes: cac2661c53f3 ("esp4: Avoid skb_cow_data whenever possible")
Fixes: 03e2a30f6a27 ("esp6: Avoid skb_cow_data whenever possible")
Fixes: 7da0dde68486 ("ip, udp: Support MSG_SPLICE_PAGES")
Fixes: 6d8192bd69bb ("ip6, udp6: Support MSG_SPLICE_PAGES")
Reported-by: Hyunwoo Kim <imv4bel@gmail.com>
Reported-by: Kuan-Ting Chen <h3xrabbit@gmail.com>
Tested-by: Hyunwoo Kim <imv4bel@gmail.com>
Cc: stable@vger.kernel.org
Signed-off-by: Kuan-Ting Chen <h3xrabbit@gmail.com>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
Signed-off-by: CKI Backport Bot <cki-ci-bot+cki-gitlab-backport-bot@redhat.com>
Signed-off-by: Sabrina Dubroca <sdubroca@redhat.com>
diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c
index b8c7c8b42c0a..0c5cd78991d9 100644
--- a/net/ipv4/esp4.c
+++ b/net/ipv4/esp4.c
@@ -869,7 +869,8 @@ static int esp_input(struct xfrm_state *x, struct sk_buff *skb)
nfrags = 1;
goto skip_cow;
- } else if (!skb_has_frag_list(skb)) {
+ } else if (!skb_has_frag_list(skb) &&
+ !skb_has_shared_frag(skb)) {
nfrags = skb_shinfo(skb)->nr_frags;
nfrags++;
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index 14d7d98fa417..58f155e70049 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -1236,6 +1236,8 @@ static int __ip_append_data(struct sock *sk,
if (err < 0)
goto error;
copy = err;
+ if (!(flags & MSG_NO_SHARED_FRAGS))
+ skb_shinfo(skb)->flags |= SKBFL_SHARED_FRAG;
wmem_alloc_delta += copy;
} else if (!zc) {
int i = skb_shinfo(skb)->nr_frags;
diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c
index 9c4c7b1f2955..0ecbb54bbdf0 100644
--- a/net/ipv6/esp6.c
+++ b/net/ipv6/esp6.c
@@ -911,7 +911,8 @@ static int esp6_input(struct xfrm_state *x, struct sk_buff *skb)
nfrags = 1;
goto skip_cow;
- } else if (!skb_has_frag_list(skb)) {
+ } else if (!skb_has_frag_list(skb) &&
+ !skb_has_shared_frag(skb)) {
nfrags = skb_shinfo(skb)->nr_frags;
nfrags++;
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index ca5853d5298a..2ba9df0262c9 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -1772,6 +1772,8 @@ static int __ip6_append_data(struct sock *sk,
if (err < 0)
goto error;
copy = err;
+ if (!(flags & MSG_NO_SHARED_FRAGS))
+ skb_shinfo(skb)->flags |= SKBFL_SHARED_FRAG;
wmem_alloc_delta += copy;
} else if (!zc) {
int i = skb_shinfo(skb)->nr_frags;
--
2.50.1 (Apple Git-155)

View File

@ -0,0 +1,86 @@
From 8d155e2d1c4102f74f82a2bf9c016164bb0f7384 Mon Sep 17 00:00:00 2001
From: Nathan Rebello <nathan.c.rebello@gmail.com>
Date: Thu, 2 Apr 2026 04:52:59 -0400
Subject: [PATCH] usbip: validate number_of_packets in usbip_pack_ret_submit()
commit 2ab833a16a825373aad2ba7d54b572b277e95b71 upstream.
When a USB/IP client receives a RET_SUBMIT response,
usbip_pack_ret_submit() unconditionally overwrites
urb->number_of_packets from the network PDU. This value is
subsequently used as the loop bound in usbip_recv_iso() and
usbip_pad_iso() to iterate over urb->iso_frame_desc[], a flexible
array whose size was fixed at URB allocation time based on the
*original* number_of_packets from the CMD_SUBMIT.
A malicious USB/IP server can set number_of_packets in the response
to a value larger than what was originally submitted, causing a heap
out-of-bounds write when usbip_recv_iso() writes to
urb->iso_frame_desc[i] beyond the allocated region.
KASAN confirmed this with kernel 7.0.0-rc5:
BUG: KASAN: slab-out-of-bounds in usbip_recv_iso+0x46a/0x640
Write of size 4 at addr ffff888106351d40 by task vhci_rx/69
The buggy address is located 0 bytes to the right of
allocated 320-byte region [ffff888106351c00, ffff888106351d40)
The server side (stub_rx.c) and gadget side (vudc_rx.c) already
validate number_of_packets in the CMD_SUBMIT path since commits
c6688ef9f297 ("usbip: fix stub_rx: harden CMD_SUBMIT path to handle
malicious input") and b78d830f0049 ("usbip: fix vudc_rx: harden
CMD_SUBMIT path to handle malicious input"). The server side validates
against USBIP_MAX_ISO_PACKETS because no URB exists yet at that point.
On the client side we have the original URB, so we can use the tighter
bound: the response must not exceed the original number_of_packets.
This mirrors the existing validation of actual_length against
transfer_buffer_length in usbip_recv_xbuff(), which checks the
response value against the original allocation size.
Kelvin Mbogo's series ("usb: usbip: fix integer overflow in
usbip_recv_iso()", v2) hardens the receive-side functions themselves;
this patch complements that work by catching the bad value at its
source -- in usbip_pack_ret_submit() before the overwrite -- and
using the tighter per-URB allocation bound rather than the global
USBIP_MAX_ISO_PACKETS limit.
Fix this by checking rpdu->number_of_packets against
urb->number_of_packets in usbip_pack_ret_submit() before the
overwrite. On violation, clamp to zero so that usbip_recv_iso() and
usbip_pad_iso() safely return early.
Fixes: 1325f85fa49f ("staging: usbip: bugfix add number of packets for isochronous frames")
Cc: stable <stable@kernel.org>
Acked-by: Shuah Khan <skhan@linuxfoundation.org>
Signed-off-by: Nathan Rebello <nathan.c.rebello@gmail.com>
Link: https://patch.msgid.link/20260402085259.234-1-nathan.c.rebello@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
diff --git a/drivers/usb/usbip/usbip_common.c b/drivers/usb/usbip/usbip_common.c
index a2b2da1255dd..ba9e7c616e12 100644
--- a/drivers/usb/usbip/usbip_common.c
+++ b/drivers/usb/usbip/usbip_common.c
@@ -470,6 +470,18 @@ static void usbip_pack_ret_submit(struct usbip_header *pdu, struct urb *urb,
urb->status = rpdu->status;
urb->actual_length = rpdu->actual_length;
urb->start_frame = rpdu->start_frame;
+ /*
+ * The number_of_packets field determines the length of
+ * iso_frame_desc[], which is a flexible array allocated
+ * at URB creation time. A response must never claim more
+ * packets than originally submitted; doing so would cause
+ * an out-of-bounds write in usbip_recv_iso() and
+ * usbip_pad_iso(). Clamp to zero on violation so both
+ * functions safely return early.
+ */
+ if (rpdu->number_of_packets < 0 ||
+ rpdu->number_of_packets > urb->number_of_packets)
+ rpdu->number_of_packets = 0;
urb->number_of_packets = rpdu->number_of_packets;
urb->error_count = rpdu->error_count;
}
--
2.50.1 (Apple Git-155)

View File

@ -0,0 +1,54 @@
From c9e16b3352bcbb7a12a4ec6237721659201843f7 Mon Sep 17 00:00:00 2001
From: Kamal Heib <kheib@redhat.com>
Date: Tue, 7 Apr 2026 21:44:30 -0400
Subject: [PATCH] RDMA/umem: Fix double dma_buf_unpin in failure path
JIRA: https://redhat.atlassian.net/browse/RHEL-163515
commit 104016eb671e19709721c1b0048dd912dc2e96be
Author: Jacob Moroni <jmoroni@google.com>
Date: Tue Feb 24 23:41:53 2026 +0000
RDMA/umem: Fix double dma_buf_unpin in failure path
In ib_umem_dmabuf_get_pinned_with_dma_device(), the call to
ib_umem_dmabuf_map_pages() can fail. If this occurs, the dmabuf
is immediately unpinned but the umem_dmabuf->pinned flag is still
set. Then, when ib_umem_release() is called, it calls
ib_umem_dmabuf_revoke() which will call dma_buf_unpin() again.
Fix this by removing the immediate unpin upon failure and just let
the ib_umem_release/revoke path handle it. This also ensures the
proper unmap-unpin unwind ordering if the dmabuf_map_pages call
happened to fail due to dma_resv_wait_timeout (and therefore has
a non-NULL umem_dmabuf->sgt).
Fixes: 1e4df4a21c5a ("RDMA/umem: Allow pinned dmabuf umem usage")
Signed-off-by: Jacob Moroni <jmoroni@google.com>
Link: https://patch.msgid.link/20260224234153.1207849-1-jmoroni@google.com
Signed-off-by: Leon Romanovsky <leon@kernel.org>
Signed-off-by: Kamal Heib <kheib@redhat.com>
diff --git a/drivers/infiniband/core/umem_dmabuf.c b/drivers/infiniband/core/umem_dmabuf.c
index 939da49b0dcc..420ee3a495b5 100644
--- a/drivers/infiniband/core/umem_dmabuf.c
+++ b/drivers/infiniband/core/umem_dmabuf.c
@@ -218,13 +218,11 @@ ib_umem_dmabuf_get_pinned_with_dma_device(struct ib_device *device,
err = ib_umem_dmabuf_map_pages(umem_dmabuf);
if (err)
- goto err_unpin;
+ goto err_release;
dma_resv_unlock(umem_dmabuf->attach->dmabuf->resv);
return umem_dmabuf;
-err_unpin:
- dma_buf_unpin(umem_dmabuf->attach);
err_release:
dma_resv_unlock(umem_dmabuf->attach->dmabuf->resv);
ib_umem_release(&umem_dmabuf->umem);
--
2.50.1 (Apple Git-155)

View File

@ -0,0 +1,71 @@
diff --git a/include/linux/sched.h b/include/linux/sched.h
index fb22590..b7b2ea6 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -981,6 +981,9 @@ struct task_struct {
unsigned sched_migrated:1;
unsigned sched_task_hot:1;
+ /* Save user-dumpable when mm goes away */
+ RH_KABI_FILL_HOLE(unsigned user_dumpable:1)
+
/* Force alignment to the next boundary: */
unsigned :0;
diff --git a/kernel/exit.c b/kernel/exit.c
index 86df8fa..a310ea8 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -563,6 +563,7 @@ static void exit_mm(void)
*/
smp_mb__after_spinlock();
local_irq_disable();
+ current->user_dumpable = (get_dumpable(mm) == SUID_DUMP_USER);
current->mm = NULL;
membarrier_update_current_mm(NULL);
enter_lazy_tlb(mm, current);
diff --git a/kernel/ptrace.c b/kernel/ptrace.c
index d5f89f9..75bcc15 100644
--- a/kernel/ptrace.c
+++ b/kernel/ptrace.c
@@ -272,11 +272,24 @@ static bool ptrace_has_cap(struct user_namespace *ns, unsigned int mode)
return ns_capable(ns, CAP_SYS_PTRACE);
}
+static bool task_still_dumpable(struct task_struct *task, unsigned int mode)
+{
+ struct mm_struct *mm = task->mm;
+ if (mm) {
+ if (get_dumpable(mm) == SUID_DUMP_USER)
+ return true;
+ return ptrace_has_cap(mm->user_ns, mode);
+ }
+
+ if (task->user_dumpable)
+ return true;
+ return ptrace_has_cap(&init_user_ns, mode);
+}
+
/* Returns 0 on success, -errno on denial. */
static int __ptrace_may_access(struct task_struct *task, unsigned int mode)
{
const struct cred *cred = current_cred(), *tcred;
- struct mm_struct *mm;
kuid_t caller_uid;
kgid_t caller_gid;
@@ -337,11 +350,8 @@ static int __ptrace_may_access(struct task_struct *task, unsigned int mode)
* Pairs with a write barrier in commit_creds().
*/
smp_rmb();
- mm = task->mm;
- if (mm &&
- ((get_dumpable(mm) != SUID_DUMP_USER) &&
- !ptrace_has_cap(mm->user_ns, mode)))
- return -EPERM;
+ if (!task_still_dumpable(task, mode))
+ return -EPERM;
return security_ptrace_access_check(task, mode);
}

View File

@ -0,0 +1,48 @@
From 760e1addc27ba1a7beb4a0a7e8b3e9ec49e7a34e Mon Sep 17 00:00:00 2001
From: William Bowling <vakzz@zellic.io>
Date: Wed, 13 May 2026 04:16:35 +0000
Subject: [PATCH] net: skbuff: preserve shared-frag marker during coalescing
commit f84eca5817390257cef78013d0112481c503b4a3 upstream.
skb_try_coalesce() can attach paged frags from @from to @to. If @from
has SKBFL_SHARED_FRAG set, the resulting @to skb can contain the same
externally-owned or page-cache-backed frags, but the shared-frag marker
is currently lost.
That breaks the invariant relied on by later in-place writers. In
particular, ESP input checks skb_has_shared_frag() before deciding
whether an uncloned nonlinear skb can skip skb_cow_data(). If TCP
receive coalescing has moved shared frags into an unmarked skb, ESP can
see skb_has_shared_frag() as false and decrypt in place over page-cache
backed frags.
Propagate SKBFL_SHARED_FRAG when skb_try_coalesce() transfers paged
frags. The tailroom copy path does not need the marker because it copies
bytes into @to's linear data rather than transferring frag descriptors.
Fixes: cef401de7be8 ("net: fix possible wrong checksum generation")
Fixes: f4c50a4034e6 ("xfrm: esp: avoid in-place decrypt on shared skb frags")
Signed-off-by: William Bowling <vakzz@zellic.io>
Reviewed-by: Eric Dumazet <edumazet@google.com>
Tested-by: Jiayuan Chen <jiayuan.chen@linux.dev>
Link: https://patch.msgid.link/20260513041635.1289541-1-vakzz@zellic.io
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index a753d01b587b..00d60588fb09 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -6066,6 +6066,8 @@ bool skb_try_coalesce(struct sk_buff *to, struct sk_buff *from,
from_shinfo->frags,
from_shinfo->nr_frags * sizeof(skb_frag_t));
to_shinfo->nr_frags += from_shinfo->nr_frags;
+ if (from_shinfo->nr_frags)
+ to_shinfo->flags |= from_shinfo->flags & SKBFL_SHARED_FRAG;
if (!skb_cloned(from))
from_shinfo->nr_frags = 0;
--
2.50.1 (Apple Git-155)

View File

@ -0,0 +1,152 @@
From fc6eb39c55e97df2f94ad974b8a5bbcd019da2c8 Mon Sep 17 00:00:00 2001
From: Hyunwoo Kim <imv4bel@gmail.com>
Date: Sat, 16 May 2026 07:28:53 +0900
Subject: [PATCH] net: skbuff: propagate shared-frag marker through
frag-transfer helpers
commit 48f6a5356a33dd78e7144ae1faef95ffc990aae0 upstream.
Two frag-transfer helpers (__pskb_copy_fclone() and skb_shift()) fail
to propagate the SKBFL_SHARED_FRAG bit in skb_shinfo()->flags when
moving frags from source to destination. __pskb_copy_fclone() defers
the rest of the shinfo metadata to skb_copy_header() after copying
frag descriptors, but that helper only carries over gso_{size,segs,
type} and never touches skb_shinfo()->flags; skb_shift() moves frag
descriptors directly and leaves flags untouched. As a result, the
destination skb keeps a reference to the same externally-owned or
page-cache-backed pages while reporting skb_has_shared_frag() as
false.
The mismatch is harmful in any in-place writer that uses
skb_has_shared_frag() to decide whether shared pages must be detoured
through skb_cow_data(). ESP input is one such writer (esp4.c,
esp6.c), and a single nft 'dup to <local>' rule -- or any other
nf_dup_ipv4() / xt_TEE caller -- is enough to land a pskb_copy()'d
skb in esp_input() with the marker stripped, letting an unprivileged
user write into the page cache of a root-owned read-only file via
authencesn-ESN stray writes.
Set SKBFL_SHARED_FRAG on the destination whenever frag descriptors
were actually moved from the source. skb_copy() and skb_copy_expand()
share skb_copy_header() too but linearize all paged data into freshly
allocated head storage and emerge with nr_frags == 0, so
skb_has_shared_frag() returns false on its own; they need no change.
The same omission exists in skb_gro_receive() and skb_gro_receive_list().
The former moves the incoming skb's frag descriptors into the
accumulator's last sub-skb via two paths (a direct frag-move loop and
the head_frag + memcpy path); the latter chains the incoming skb whole
onto p's frag_list. Downstream skb_segment() reads only
skb_shinfo(p)->flags, and skb_segment_list() reuses each sub-skb's
shinfo as the nskb -- both p and lp must carry the marker.
The same omission also exists in tcp_clone_payload(), which builds an
MTU probe skb by moving frag descriptors from skbs on sk_write_queue
into a freshly allocated nskb. The helper falls into the same family
and warrants the same fix for consistency; no TCP TX-side in-place
writer is currently known to reach a user page through this gap, but
a future consumer depending on the marker would regress silently.
The same omission exists in skb_segment(): the per-iteration flag
merge takes only head_skb's flag, and the inner switch that rebinds
frag_skb to list_skb on head_skb-frags exhaustion does not fold the
new frag_skb's flag into nskb. Fold frag_skb's flag at both sites
so segments drawing frags from frag_list members carry the marker.
Fixes: cef401de7be8 ("net: fix possible wrong checksum generation")
Fixes: f4c50a4034e6 ("xfrm: esp: avoid in-place decrypt on shared skb frags")
Suggested-by: Sabrina Dubroca <sd@queasysnail.net>
Suggested-by: Sultan Alsawaf <sultan@kerneltoast.com>
Suggested-by: Ben Hutchings <ben@decadent.org.uk>
Suggested-by: Lin Ma <malin89@huawei.com>
Suggested-by: Jingguo Tan <tanjingguo@huawei.com>
Suggested-by: Aaron Esau <aaron1esau@gmail.com>
Cc: stable@vger.kernel.org
Signed-off-by: Hyunwoo Kim <imv4bel@gmail.com>
Tested-by: Rajat Gupta <rajat.gupta@oss.qualcomm.com>
Link: https://patch.msgid.link/ageeJfJHwgzmKXbh@v4bel
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
diff --git a/net/core/gro.c b/net/core/gro.c
index ac498c9f82cf..f5c80c2f69df 100644
--- a/net/core/gro.c
+++ b/net/core/gro.c
@@ -214,10 +214,12 @@ int skb_gro_receive(struct sk_buff *p, struct sk_buff *skb)
p->data_len += len;
p->truesize += delta_truesize;
p->len += len;
+ skb_shinfo(p)->flags |= skbinfo->flags & SKBFL_SHARED_FRAG;
if (lp != p) {
lp->data_len += len;
lp->truesize += delta_truesize;
lp->len += len;
+ skb_shinfo(lp)->flags |= skbinfo->flags & SKBFL_SHARED_FRAG;
}
NAPI_GRO_CB(skb)->same_flow = 1;
return 0;
@@ -245,6 +247,8 @@ int skb_gro_receive_list(struct sk_buff *p, struct sk_buff *skb)
p->truesize += skb->truesize;
p->len += skb->len;
+ skb_shinfo(p)->flags |= skb_shinfo(skb)->flags & SKBFL_SHARED_FRAG;
+
NAPI_GRO_CB(skb)->same_flow = 1;
return 0;
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 00d60588fb09..aa9e91488473 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -2214,6 +2214,7 @@ struct sk_buff *__pskb_copy_fclone(struct sk_buff *skb, int headroom,
skb_frag_ref(skb, i);
}
skb_shinfo(n)->nr_frags = i;
+ skb_shinfo(n)->flags |= skb_shinfo(skb)->flags & SKBFL_SHARED_FRAG;
}
if (skb_has_frag_list(skb)) {
@@ -4289,6 +4290,8 @@ int skb_shift(struct sk_buff *tgt, struct sk_buff *skb, int shiftlen)
tgt->ip_summed = CHECKSUM_PARTIAL;
skb->ip_summed = CHECKSUM_PARTIAL;
+ skb_shinfo(tgt)->flags |= skb_shinfo(skb)->flags & SKBFL_SHARED_FRAG;
+
skb_len_add(skb, -shiftlen);
skb_len_add(tgt, shiftlen);
@@ -4899,7 +4902,8 @@ struct sk_buff *skb_segment(struct sk_buff *head_skb,
skb_copy_from_linear_data_offset(head_skb, offset,
skb_put(nskb, hsize), hsize);
- skb_shinfo(nskb)->flags |= skb_shinfo(head_skb)->flags &
+ skb_shinfo(nskb)->flags |= (skb_shinfo(head_skb)->flags |
+ skb_shinfo(frag_skb)->flags) &
SKBFL_SHARED_FRAG;
if (skb_zerocopy_clone(nskb, frag_skb, GFP_ATOMIC))
@@ -4916,6 +4920,9 @@ struct sk_buff *skb_segment(struct sk_buff *head_skb,
nfrags = skb_shinfo(list_skb)->nr_frags;
frag = skb_shinfo(list_skb)->frags;
frag_skb = list_skb;
+
+ skb_shinfo(nskb)->flags |= skb_shinfo(frag_skb)->flags & SKBFL_SHARED_FRAG;
+
if (!skb_headlen(list_skb)) {
BUG_ON(!nfrags);
} else {
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index 33c2fb60d056..c76672f544be 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -2391,6 +2391,7 @@ static int tcp_clone_payload(struct sock *sk, struct sk_buff *to,
todo = min_t(int, skb_frag_size(fragfrom),
probe_size - len);
len += todo;
+ skb_shinfo(to)->flags |= skb_shinfo(skb)->flags & SKBFL_SHARED_FRAG;
if (lastfrag &&
skb_frag_page(fragfrom) == skb_frag_page(lastfrag) &&
skb_frag_off(fragfrom) == skb_frag_off(lastfrag) +
--
2.50.1 (Apple Git-155)

View File

@ -182,7 +182,7 @@ Summary: The Linux kernel
# This is needed to do merge window version magic
%define patchlevel 12
# This allows pkg_release to have configurable %%{?dist} tag
%define specrelease 211.7.4%{?buildid}%{?dist}
%define specrelease 211.16.1%{?buildid}%{?dist}
# This defines the kabi tarball version
%define kabiversion 6.12.0-211.7.1.el10_2
@ -1138,13 +1138,64 @@ Patch2007: 0007-Bring-back-deprecated-pci-ids-to-be2iscsi-driver.patch
Patch2008: 0008-Bring-back-deprecated-pci-ids-to-megaraid_sas-driver.patch
Patch2009: 0009-Bring-back-deprecated-pci-ids-to-mpt3sas-driver.patch
Patch2010: 0001-Keep-fs-btrfs-files-in-modules-package.patch
Patch1100: 1100-CVE-2026-31431-crypto-Copy-Fail-fixes.patch
Patch1101: 1101-xfrm-esp-avoid-in-place-decrypt-shared-skb-frags.patch
Patch1102: 1102-rxrpc-linearize-paged-frags.patch
Patch1103: 1103-net-skbuff-propagate-shared-frag-marker.patch
Patch1104: 1104-ptrace-require-cap-on-mm-less-task.patch
Patch1105: 1105-smb-client-reject-userspace-cifs.spnego-descriptions.patch
Patch1106: 1106-net-sched-make-cake-enqueue-return-net-xmit-cn-when-past-buf.patch
Patch1107: 1107-net-sched-sch-cake-fix-incorrect-qlen-reduction-in-cake-drop.patch
Patch1108: 1108-rdma-bnxt-re-support-extended-stats-for-thor2-vf.patch
Patch1109: 1109-rdma-bnxt-re-fix-size-of-uverbs-copy-to-in-bnxt-re-method-ge.patch
Patch1110: 1110-rdma-bnxt-re-support-2g-message-size.patch
Patch1111: 1111-rdma-bnxt-re-use-macro-instead-of-hard-coded-value.patch
Patch1112: 1112-rdma-bnxt-re-fix-incorrect-display-of-inactivity-cp-in-debug.patch
Patch1113: 1113-rdma-bnxt-re-fix-missing-error-handling-for-tx-queue.patch
Patch1114: 1114-rdma-bnxt-re-fix-return-code-of-bnxt-re-configure-cc.patch
Patch1115: 1115-rdma-bnxt-re-convert-timeouts-to-secs-to-jiffies.patch
Patch1116: 1116-net-openvswitch-avoid-releasing-netdev-before-teardown-compl.patch
Patch1117: 1117-ionic-fix-persistent-mac-address-override-on-pf.patch
Patch1118: 1118-net-hv-netvsc-reject-rss-hash-key-programming-without-rx-ind.patch
Patch1119: 1119-scsi-qla2xxx-fix-improper-freeing-of-purex-item.patch
Patch1120: 1120-smb-client-fix-krb5-mount-with-username-option.patch
Patch1121: 1121-alsa-hda-tas2781-ignore-reset-check-for-spi-device.patch
Patch1122: 1122-i40e-drop-udp-tunnel-get-rx-info-call-from-i40e-open.patch
Patch1123: 1123-ice-drop-udp-tunnel-get-rx-info-call-from-ndo-open.patch
Patch1124: 1124-x86-boot-handle-relative-config-efi-sbat-file-file-paths.patch
Patch1125: 1125-net-sched-only-allow-act-ct-to-bind-to-clsact-ingress-qdiscs.patch
Patch1126: 1126-asoc-sdca-tidy-up-some-memory-allocations.patch
Patch1127: 1127-asoc-sdca-handle-config-pm-sleep-not-being-set.patch
Patch1128: 1128-asoc-sdca-update-counting-of-su-ge-dapm-routes.patch
Patch1129: 1129-asoc-add-snd-soc-lookup-component-by-name-helper.patch
Patch1130: 1130-asoc-soc-sdw-utils-partial-match-the-codec-name.patch
Patch1131: 1131-asoc-soc-sdw-utils-remove-index-from-sdca-codec-name.patch
Patch1132: 1132-kvm-x86-mmu-drop-zap-existing-present-spte-even-when-creatin.patch
Patch1133: 1133-kvm-x86-mmu-only-warn-in-direct-mmus-when-overwriting-shadow.patch
Patch1134: 1134-nfsd-fix-heap-overflow-in-nfsv4-0-lock-replay-cache.patch
Patch1135: 1135-net-af-can-do-not-leave-a-dangling-sk-pointer-in-can-create.patch
Patch1136: 1136-crypto-asymmetric-keys-prevent-overflow-in-asymmetric-key-ge.patch
Patch1137: 1137-drm-i915-dsc-add-helper-to-enable-the-dsc-configuration-for-.patch
Patch1138: 1138-drm-i915-dp-ensure-the-fec-state-stays-disabled-for-uhbr-lin.patch
Patch1139: 1139-drm-i915-dp-export-helper-to-determine-if-fec-on-non-uhbr-li.patch
Patch1140: 1140-drm-i915-dp-mst-reuse-the-dp-sst-helper-function-to-compute-.patch
Patch1141: 1141-drm-i915-dp-mst-track-dsc-enabled-status-on-the-mst-link.patch
Patch1142: 1142-drm-i915-dp-mst-recompute-all-mst-link-crtcs-if-dsc-gets-ena.patch
Patch1143: 1143-drm-i915-dp-fix-panel-replay-when-dsc-is-enabled.patch
Patch1144: 1144-bluetooth-sco-fix-use-after-free-in-sco-recv-frame-due-to-mi.patch
Patch1145: 1145-scsi-storvsc-handle-persistent-reserve-in-truncation-for-hyp.patch
Patch1146: 1146-crypto-af-alg-fix-null-pointer-dereference-in-scatterwalk.patch
Patch1147: 1147-crypto-algif-aead-revert-to-operating-out-of-place.patch
Patch1148: 1148-crypto-af-alg-limit-rx-sg-extraction-by-receive-buffer-budge.patch
Patch1149: 1149-crypto-af-alg-fix-page-reassignment-overflow-in-af-alg-pull-.patch
Patch1150: 1150-crypto-authencesn-reject-too-short-aad-assoclen-8-to-match-e.patch
Patch1151: 1151-crypto-authencesn-do-not-place-hiseq-at-end-of-dst-for-out-o.patch
Patch1152: 1152-crypto-authencesn-fix-src-offset-when-decrypting-in-place.patch
Patch1153: 1153-crypto-authencesn-reject-short-ahash-digests-during-instance.patch
Patch1154: 1154-crypto-algif-aead-fix-minimum-rx-size-check-for-decryption.patch
Patch1155: 1155-crypto-algif-aead-snapshot-iv-for-async-aead-requests.patch
Patch1156: 1156-xfrm-esp-avoid-in-place-decrypt-on-shared-skb-frags.patch
Patch1157: 1157-usbip-validate-number-of-packets-in-usbip-pack-ret-submit.patch
Patch1158: 1158-rdma-umem-fix-double-dma-buf-unpin-in-failure-path.patch
Patch1159: 1159-ptrace-slightly-saner-get-dumpable-logic.patch
Patch1160: 1160-net-skbuff-preserve-shared-frag-marker-during-coalescing.patch
Patch1161: 1161-net-skbuff-propagate-shared-frag-marker-through-frag-transfe.patch
# END OF PATCH DEFINITIONS
%description
@ -2004,14 +2055,65 @@ ApplyPatch 0007-Bring-back-deprecated-pci-ids-to-be2iscsi-driver.patch
ApplyPatch 0008-Bring-back-deprecated-pci-ids-to-megaraid_sas-driver.patch
ApplyPatch 0009-Bring-back-deprecated-pci-ids-to-mpt3sas-driver.patch
ApplyPatch 0001-Keep-fs-btrfs-files-in-modules-package.patch
ApplyPatch 1100-CVE-2026-31431-crypto-Copy-Fail-fixes.patch
ApplyPatch 1101-xfrm-esp-avoid-in-place-decrypt-shared-skb-frags.patch
ApplyPatch 1102-rxrpc-linearize-paged-frags.patch
ApplyPatch 1103-net-skbuff-propagate-shared-frag-marker.patch
ApplyPatch 1104-ptrace-require-cap-on-mm-less-task.patch
ApplyPatch 1105-smb-client-reject-userspace-cifs.spnego-descriptions.patch
%{log_msg "End of patch applications"}
ApplyPatch 1106-net-sched-make-cake-enqueue-return-net-xmit-cn-when-past-buf.patch
ApplyPatch 1107-net-sched-sch-cake-fix-incorrect-qlen-reduction-in-cake-drop.patch
ApplyPatch 1108-rdma-bnxt-re-support-extended-stats-for-thor2-vf.patch
ApplyPatch 1109-rdma-bnxt-re-fix-size-of-uverbs-copy-to-in-bnxt-re-method-ge.patch
ApplyPatch 1110-rdma-bnxt-re-support-2g-message-size.patch
ApplyPatch 1111-rdma-bnxt-re-use-macro-instead-of-hard-coded-value.patch
ApplyPatch 1112-rdma-bnxt-re-fix-incorrect-display-of-inactivity-cp-in-debug.patch
ApplyPatch 1113-rdma-bnxt-re-fix-missing-error-handling-for-tx-queue.patch
ApplyPatch 1114-rdma-bnxt-re-fix-return-code-of-bnxt-re-configure-cc.patch
ApplyPatch 1115-rdma-bnxt-re-convert-timeouts-to-secs-to-jiffies.patch
ApplyPatch 1116-net-openvswitch-avoid-releasing-netdev-before-teardown-compl.patch
ApplyPatch 1117-ionic-fix-persistent-mac-address-override-on-pf.patch
ApplyPatch 1118-net-hv-netvsc-reject-rss-hash-key-programming-without-rx-ind.patch
ApplyPatch 1119-scsi-qla2xxx-fix-improper-freeing-of-purex-item.patch
ApplyPatch 1120-smb-client-fix-krb5-mount-with-username-option.patch
ApplyPatch 1121-alsa-hda-tas2781-ignore-reset-check-for-spi-device.patch
ApplyPatch 1122-i40e-drop-udp-tunnel-get-rx-info-call-from-i40e-open.patch
ApplyPatch 1123-ice-drop-udp-tunnel-get-rx-info-call-from-ndo-open.patch
ApplyPatch 1124-x86-boot-handle-relative-config-efi-sbat-file-file-paths.patch
ApplyPatch 1125-net-sched-only-allow-act-ct-to-bind-to-clsact-ingress-qdiscs.patch
ApplyPatch 1126-asoc-sdca-tidy-up-some-memory-allocations.patch
ApplyPatch 1127-asoc-sdca-handle-config-pm-sleep-not-being-set.patch
ApplyPatch 1128-asoc-sdca-update-counting-of-su-ge-dapm-routes.patch
ApplyPatch 1129-asoc-add-snd-soc-lookup-component-by-name-helper.patch
ApplyPatch 1130-asoc-soc-sdw-utils-partial-match-the-codec-name.patch
ApplyPatch 1131-asoc-soc-sdw-utils-remove-index-from-sdca-codec-name.patch
ApplyPatch 1132-kvm-x86-mmu-drop-zap-existing-present-spte-even-when-creatin.patch
ApplyPatch 1133-kvm-x86-mmu-only-warn-in-direct-mmus-when-overwriting-shadow.patch
ApplyPatch 1134-nfsd-fix-heap-overflow-in-nfsv4-0-lock-replay-cache.patch
ApplyPatch 1135-net-af-can-do-not-leave-a-dangling-sk-pointer-in-can-create.patch
ApplyPatch 1136-crypto-asymmetric-keys-prevent-overflow-in-asymmetric-key-ge.patch
ApplyPatch 1137-drm-i915-dsc-add-helper-to-enable-the-dsc-configuration-for-.patch
ApplyPatch 1138-drm-i915-dp-ensure-the-fec-state-stays-disabled-for-uhbr-lin.patch
ApplyPatch 1139-drm-i915-dp-export-helper-to-determine-if-fec-on-non-uhbr-li.patch
ApplyPatch 1140-drm-i915-dp-mst-reuse-the-dp-sst-helper-function-to-compute-.patch
ApplyPatch 1141-drm-i915-dp-mst-track-dsc-enabled-status-on-the-mst-link.patch
ApplyPatch 1142-drm-i915-dp-mst-recompute-all-mst-link-crtcs-if-dsc-gets-ena.patch
ApplyPatch 1143-drm-i915-dp-fix-panel-replay-when-dsc-is-enabled.patch
ApplyPatch 1144-bluetooth-sco-fix-use-after-free-in-sco-recv-frame-due-to-mi.patch
ApplyPatch 1145-scsi-storvsc-handle-persistent-reserve-in-truncation-for-hyp.patch
ApplyPatch 1146-crypto-af-alg-fix-null-pointer-dereference-in-scatterwalk.patch
ApplyPatch 1147-crypto-algif-aead-revert-to-operating-out-of-place.patch
ApplyPatch 1148-crypto-af-alg-limit-rx-sg-extraction-by-receive-buffer-budge.patch
ApplyPatch 1149-crypto-af-alg-fix-page-reassignment-overflow-in-af-alg-pull-.patch
ApplyPatch 1150-crypto-authencesn-reject-too-short-aad-assoclen-8-to-match-e.patch
ApplyPatch 1151-crypto-authencesn-do-not-place-hiseq-at-end-of-dst-for-out-o.patch
ApplyPatch 1152-crypto-authencesn-fix-src-offset-when-decrypting-in-place.patch
ApplyPatch 1153-crypto-authencesn-reject-short-ahash-digests-during-instance.patch
ApplyPatch 1154-crypto-algif-aead-fix-minimum-rx-size-check-for-decryption.patch
ApplyPatch 1155-crypto-algif-aead-snapshot-iv-for-async-aead-requests.patch
ApplyPatch 1156-xfrm-esp-avoid-in-place-decrypt-on-shared-skb-frags.patch
ApplyPatch 1157-usbip-validate-number-of-packets-in-usbip-pack-ret-submit.patch
ApplyPatch 1158-rdma-umem-fix-double-dma-buf-unpin-in-failure-path.patch
ApplyPatch 1159-ptrace-slightly-saner-get-dumpable-logic.patch
ApplyPatch 1160-net-skbuff-preserve-shared-frag-marker-during-coalescing.patch
ApplyPatch 1161-net-skbuff-propagate-shared-frag-marker-through-frag-transfe.patch
# END OF PATCH APPLICATIONS
# Any further pre-build tree manipulations happen here.
@ -4516,6 +4618,86 @@ fi\
#
#
%changelog
* Sun Jun 07 2026 Andrew Lukoshko <alukoshko@almalinux.org> - 6.12.0-211.16.1
- Recreate RHEL 6.12.0-211.16.1 from CentOS Stream 10 and upstream stable backports (1106-1161)
- Drop 211.7.x security-ahead patches superseded by the RHEL backports (1100-1104: crypto authencesn/algif, xfrm-esp, rxrpc, net-skbuff fragnesia, ptrace)
- Keep the smb cifs.spnego ahead-fix (1105)
- RHEL changelog for 211.8.1..211.16.1 follows:
* Mon May 18 2026 CKI KWF Bot <cki-ci-bot+kwf-gitlab-com@redhat.com> [6.12.0-211.16.1.el10_2]
- net: skbuff: propagate shared-frag marker through frag-transfer helpers (Sabrina Dubroca) [RHEL-176053] {CVE-2026-46300}
- net: skbuff: preserve shared-frag marker during coalescing (Sabrina Dubroca) [RHEL-176053] {CVE-2026-46300}
- ptrace: slightly saner 'get_dumpable()' logic (Ricardo Robaina) [RHEL-176449] {CVE-2026-46333}
- RDMA/umem: Fix double dma_buf_unpin in failure path (CKI Backport Bot) [RHEL-174029] {CVE-2026-43128}
- usbip: validate number_of_packets in usbip_pack_ret_submit() (CKI Backport Bot) [RHEL-171434] {CVE-2026-31607}
* Mon May 11 2026 Patrick Talbert <ptalbert@redhat.com> [6.12.0-211.15.1.el10_2]
- xfrm: esp: avoid in-place decrypt on shared skb frags (CKI Backport Bot) [RHEL-174546] {CVE-2026-43284}
* Mon May 04 2026 Patrick Talbert <ptalbert@redhat.com> [6.12.0-211.14.1.el10_2]
- crypto: algif_aead - snapshot IV for async AEAD requests (Herbert Xu) [RHEL-172213]
- crypto: algif_aead - Fix minimum RX size check for decryption (Herbert Xu) [RHEL-172213]
- crypto: authencesn - reject short ahash digests during instance creation (Herbert Xu) [RHEL-172213]
- crypto: authencesn - Fix src offset when decrypting in-place (Herbert Xu) [RHEL-172213]
- crypto: authencesn - Do not place hiseq at end of dst for out-of-place decryption (Herbert Xu) [RHEL-172213] {CVE-2026-31431}
- crypto: authencesn - reject too-short AAD (assoclen<8) to match ESP/ESN spec (Herbert Xu) [RHEL-172213] {CVE-2026-23060}
- crypto: af_alg - Fix page reassignment overflow in af_alg_pull_tsgl (Herbert Xu) [RHEL-172213]
- crypto: af_alg - limit RX SG extraction by receive buffer budget (Herbert Xu) [RHEL-172213] {CVE-2026-31677}
- crypto: algif_aead - Revert to operating out-of-place (Herbert Xu) [RHEL-172213] {CVE-2026-31431}
- crypto: af-alg - fix NULL pointer dereference in scatterwalk (Herbert Xu) [RHEL-172213]
* Thu Apr 30 2026 CKI KWF Bot <cki-ci-bot+kwf-gitlab-com@redhat.com> [6.12.0-211.13.1.el10_2]
- scsi: storvsc: Handle PERSISTENT_RESERVE_IN truncation for Hyper-V vFC (Vitaly Kuznetsov) [RHEL-171531]
- Bluetooth: SCO: Fix use-after-free in sco_recv_frame() due to missing sock_hold (CKI Backport Bot) [RHEL-170974] {CVE-2026-31408}
* Mon Apr 27 2026 CKI KWF Bot <cki-ci-bot+kwf-gitlab-com@redhat.com> [6.12.0-211.12.1.el10_2]
- drm/i915/dp: Fix panel replay when DSC is enabled (Anusha Srivatsa) [RHEL-169354]
- drm/i915/dp_mst: Recompute all MST link CRTCs if DSC gets enabled on the link (Anusha Srivatsa) [RHEL-169354]
- drm/i915/dp_mst: Track DSC enabled status on the MST link (Anusha Srivatsa) [RHEL-169354]
- drm/i915/dp_mst: Reuse the DP-SST helper function to compute FEC config (Anusha Srivatsa) [RHEL-169354]
- drm/i915/dp: Export helper to determine if FEC on non-UHBR links is required (Anusha Srivatsa) [RHEL-169354]
- drm/i915/dp: Ensure the FEC state stays disabled for UHBR links (Anusha Srivatsa) [RHEL-169354]
- drm/i915/dsc: Add helper to enable the DSC configuration for a CRTC (Anusha Srivatsa) [RHEL-169354]
- crypto: asymmetric_keys - prevent overflow in asymmetric_key_generate_id (CKI Backport Bot) [RHEL-166932] {CVE-2025-68724}
- net: af_can: do not leave a dangling sk pointer in can_create() (CKI Backport Bot) [RHEL-162253] {CVE-2024-56603}
* Thu Apr 23 2026 CKI KWF Bot <cki-ci-bot+kwf-gitlab-com@redhat.com> [6.12.0-211.11.1.el10_2]
- nfsd: fix heap overflow in NFSv4.0 LOCK replay cache (Scott Mayhew) [RHEL-168569] {CVE-2026-31402}
- KVM: x86/mmu: Only WARN in direct MMUs when overwriting shadow-present SPTE (Paolo Bonzini) [RHEL-153716] {CVE-2026-23401}
- KVM: x86/mmu: Drop/zap existing present SPTE even when creating an MMIO SPTE (Paolo Bonzini) [RHEL-153716] {CVE-2026-23401}
* Thu Apr 23 2026 CKI KWF Bot <cki-ci-bot+kwf-gitlab-com@redhat.com> [6.12.0-211.10.1.el10_2]
- ASoC: soc_sdw_utils: remove index from sdca codec name (Jaroslav Kysela) [RHEL-163717]
- ASoC: soc_sdw_utils: partial match the codec name (Jaroslav Kysela) [RHEL-163717]
- ASoC: add snd_soc_lookup_component_by_name helper (Jaroslav Kysela) [RHEL-163717]
- ASoC: SDCA: Update counting of SU/GE DAPM routes (Jaroslav Kysela) [RHEL-163717]
- ASoC: SDCA: Handle CONFIG_PM_SLEEP not being set (Jaroslav Kysela) [RHEL-163717]
- ASoC: SDCA: Tidy up some memory allocations (Jaroslav Kysela) [RHEL-163717]
- net/sched: Only allow act_ct to bind to clsact/ingress qdiscs and shared blocks (CKI Backport Bot) [RHEL-157332] {CVE-2026-23270}
* Mon Apr 20 2026 CKI KWF Bot <cki-ci-bot+kwf-gitlab-com@redhat.com> [6.12.0-211.9.1.el10_2]
- x86/boot: Handle relative CONFIG_EFI_SBAT_FILE file paths (Oleksii Baranov) [RHEL-157855]
* Thu Apr 16 2026 CKI KWF Bot <cki-ci-bot+kwf-gitlab-com@redhat.com> [6.12.0-211.8.1.el10_2]
- ice: drop udp_tunnel_get_rx_info() call from ndo_open() (Mohammad Heib) [RHEL-165081]
- i40e: drop udp_tunnel_get_rx_info() call from i40e_open() (Mohammad Heib) [RHEL-165081]
- ALSA: hda/tas2781: Ignore reset check for SPI device (Jaroslav Kysela) [RHEL-157285]
- smb: client: fix krb5 mount with username option (Paulo Alcantara) [RHEL-158990]
- scsi: qla2xxx: Fix improper freeing of purex item (CKI Backport Bot) [RHEL-159227] {CVE-2025-68741}
- net: hv_netvsc: reject RSS hash key programming without RX indirection table (Vinay Mulugund) [RHEL-155205]
- ionic: fix persistent MAC address override on PF (Mohammad Heib) [RHEL-158206]
- net: openvswitch: Avoid releasing netdev before teardown completes (Toke Høiland-Jørgensen) [RHEL-157946]
- RDMA/bnxt_re: convert timeouts to secs_to_jiffies() (CKI Backport Bot) [RHEL-155971]
- RDMA/bnxt_re: Fix return code of bnxt_re_configure_cc (CKI Backport Bot) [RHEL-155971]
- RDMA/bnxt_re: Fix missing error handling for tx_queue (CKI Backport Bot) [RHEL-155971]
- RDMA/bnxt_re: Fix incorrect display of inactivity_cp in debugfs output (CKI Backport Bot) [RHEL-155971]
- RDMA/bnxt_re: Use macro instead of hard coded value (CKI Backport Bot) [RHEL-155971]
- RDMA/bnxt_re: Support 2G message size (CKI Backport Bot) [RHEL-155971]
- RDMA/bnxt_re: Fix size of uverbs_copy_to() in BNXT_RE_METHOD_GET_TOGGLE_MEM (CKI Backport Bot) [RHEL-155971]
- RDMA/bnxt_re: Support extended stats for Thor2 VF (CKI Backport Bot) [RHEL-155971]
- net/sched: sch_cake: Fix incorrect qlen reduction in cake_drop (Davide Caratti) [RHEL-150456] {CVE-2025-39766}
- net/sched: Make cake_enqueue return NET_XMIT_CN when past buffer_limit (Davide Caratti) [RHEL-150456] {CVE-2025-39766}
* Thu May 28 2026 Andrew Lukoshko <alukoshko@almalinux.org> - 6.12.0-211.7.4
- net: skbuff: propagate shared-frag marker through frag-transfer helpers
(refresh to upstream v5: now also covers skb_segment() and