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:
parent
b3c4cf07f6
commit
b3393f484c
@ -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);
|
||||
|
||||
@ -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
|
||||
@ -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
|
||||
@ -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) +
|
||||
@ -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
|
||||
@ -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)
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
61
1108-rdma-bnxt-re-support-extended-stats-for-thor2-vf.patch
Normal file
61
1108-rdma-bnxt-re-support-extended-stats-for-thor2-vf.patch
Normal 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)
|
||||
|
||||
@ -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)
|
||||
|
||||
127
1110-rdma-bnxt-re-support-2g-message-size.patch
Normal file
127
1110-rdma-bnxt-re-support-2g-message-size.patch
Normal 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)
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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)
|
||||
|
||||
93
1115-rdma-bnxt-re-convert-timeouts-to-secs-to-jiffies.patch
Normal file
93
1115-rdma-bnxt-re-convert-timeouts-to-secs-to-jiffies.patch
Normal 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)
|
||||
|
||||
@ -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)
|
||||
|
||||
63
1117-ionic-fix-persistent-mac-address-override-on-pf.patch
Normal file
63
1117-ionic-fix-persistent-mac-address-override-on-pf.patch
Normal 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)
|
||||
|
||||
@ -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)
|
||||
|
||||
54
1119-scsi-qla2xxx-fix-improper-freeing-of-purex-item.patch
Normal file
54
1119-scsi-qla2xxx-fix-improper-freeing-of-purex-item.patch
Normal 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)
|
||||
|
||||
74
1120-smb-client-fix-krb5-mount-with-username-option.patch
Normal file
74
1120-smb-client-fix-krb5-mount-with-username-option.patch
Normal 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)
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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)
|
||||
|
||||
71
1126-asoc-sdca-tidy-up-some-memory-allocations.patch
Normal file
71
1126-asoc-sdca-tidy-up-some-memory-allocations.patch
Normal 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)
|
||||
|
||||
70
1127-asoc-sdca-handle-config-pm-sleep-not-being-set.patch
Normal file
70
1127-asoc-sdca-handle-config-pm-sleep-not-being-set.patch
Normal 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)
|
||||
|
||||
139
1128-asoc-sdca-update-counting-of-su-ge-dapm-routes.patch
Normal file
139
1128-asoc-sdca-update-counting-of-su-ge-dapm-routes.patch
Normal 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)
|
||||
|
||||
65
1129-asoc-add-snd-soc-lookup-component-by-name-helper.patch
Normal file
65
1129-asoc-add-snd-soc-lookup-component-by-name-helper.patch
Normal 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)
|
||||
|
||||
78
1130-asoc-soc-sdw-utils-partial-match-the-codec-name.patch
Normal file
78
1130-asoc-soc-sdw-utils-partial-match-the-codec-name.patch
Normal 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)
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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)
|
||||
|
||||
101
1134-nfsd-fix-heap-overflow-in-nfsv4-0-lock-replay-cache.patch
Normal file
101
1134-nfsd-fix-heap-overflow-in-nfsv4-0-lock-replay-cache.patch
Normal 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)
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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)
|
||||
|
||||
248
1143-drm-i915-dp-fix-panel-replay-when-dsc-is-enabled.patch
Normal file
248
1143-drm-i915-dp-fix-panel-replay-when-dsc-is-enabled.patch
Normal 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)
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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)
|
||||
|
||||
327
1147-crypto-algif-aead-revert-to-operating-out-of-place.patch
Normal file
327
1147-crypto-algif-aead-revert-to-operating-out-of-place.patch
Normal 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)
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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)
|
||||
|
||||
108
1156-xfrm-esp-avoid-in-place-decrypt-on-shared-skb-frags.patch
Normal file
108
1156-xfrm-esp-avoid-in-place-decrypt-on-shared-skb-frags.patch
Normal 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)
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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)
|
||||
|
||||
71
1159-ptrace-slightly-saner-get-dumpable-logic.patch
Normal file
71
1159-ptrace-slightly-saner-get-dumpable-logic.patch
Normal 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);
|
||||
}
|
||||
@ -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)
|
||||
|
||||
@ -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)
|
||||
|
||||
204
kernel.spec
204
kernel.spec
@ -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
|
||||
|
||||
Loading…
Reference in New Issue
Block a user