diff --git a/meta-oe/recipes-connectivity/thrift/thrift/CVE-2026-45112.patch b/meta-oe/recipes-connectivity/thrift/thrift/CVE-2026-45112.patch
new file mode 100644
index 0000000000..7e4fb78911
--- /dev/null
+++ b/meta-oe/recipes-connectivity/thrift/thrift/CVE-2026-45112.patch
@@ -0,0 +1,306 @@
+From 4d68f215f05905a19dd43865fb97d170b4fc1a3b Mon Sep 17 00:00:00 2001
+From: Jens Geyer <jensg@apache.org>
+Date: Fri, 8 May 2026 21:24:30 +0200
+Subject: [PATCH] Add message byte tracking to consumeBuffer() in Java
+ transports Client: java
+
+- consumeBuffer() in TMemoryInputTransport and AutoExpandingBufferReadTransport
+  now decrements remainingMessageSize inline so fast-path buffer reads are
+  counted toward the per-message size limit
+- AutoExpandingBufferReadTransport.fill() resets remainingMessageSize at the
+  start of each frame, matching TMemoryInputTransport.reset() behavior in
+  TFramedTransport
+- TBinaryProtocol.readString() now checks stringLengthLimit before the
+  fast-path branch
+- Add TestMessageSizeLimits covering all fixed code paths
+
+Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
+
+CVE: CVE-2026-45112
+Upstream-Status: Backport [https://github.com/apache/thrift/commit/16b3673827498d1f4b05f8026d5d580b8e8f5aa2]
+
+Signed-off-by: Adarsh Jagadish Kamini <adarsh.jagadish.kamini@est.tech>
+---
+ .../thrift/protocol/TBinaryProtocol.java      |   6 +-
+ .../AutoExpandingBufferReadTransport.java     |   6 +
+ .../transport/TMemoryInputTransport.java      |   7 +-
+ .../protocol/TestMessageSizeLimits.java       | 196 ++++++++++++++++++
+ 4 files changed, 213 insertions(+), 2 deletions(-)
+ create mode 100644 lib/java/src/test/java/org/apache/thrift/protocol/TestMessageSizeLimits.java
+
+diff --git a/lib/java/src/main/java/org/apache/thrift/protocol/TBinaryProtocol.java b/lib/java/src/main/java/org/apache/thrift/protocol/TBinaryProtocol.java
+index 99c3e9302..49e82ee8a 100644
+--- a/lib/java/src/main/java/org/apache/thrift/protocol/TBinaryProtocol.java
++++ b/lib/java/src/main/java/org/apache/thrift/protocol/TBinaryProtocol.java
+@@ -458,6 +458,8 @@ public class TBinaryProtocol extends TProtocol {
+   public String readString() throws TException {
+     int size = readI32();
+ 
++    checkStringReadLength(size);
++
+     if (trans_.getBytesRemainingInBuffer() >= size) {
+       String s =
+           new String(trans_.getBuffer(), trans_.getBufferPosition(), size, StandardCharsets.UTF_8);
+@@ -465,7 +467,9 @@ public class TBinaryProtocol extends TProtocol {
+       return s;
+     }
+ 
+-    return readStringBody(size);
++    byte[] buf = new byte[size];
++    trans_.readAll(buf, 0, size);
++    return new String(buf, StandardCharsets.UTF_8);
+   }
+ 
+   public String readStringBody(int size) throws TException {
+diff --git a/lib/java/src/main/java/org/apache/thrift/transport/AutoExpandingBufferReadTransport.java b/lib/java/src/main/java/org/apache/thrift/transport/AutoExpandingBufferReadTransport.java
+index d59c657db..53b35c207 100644
+--- a/lib/java/src/main/java/org/apache/thrift/transport/AutoExpandingBufferReadTransport.java
++++ b/lib/java/src/main/java/org/apache/thrift/transport/AutoExpandingBufferReadTransport.java
+@@ -39,6 +39,7 @@ public class AutoExpandingBufferReadTransport extends TEndpointTransport {
+     inTrans.readAll(buf.array(), 0, length);
+     pos = 0;
+     limit = length;
++    resetConsumedMessageSize(-1);
+   }
+ 
+   @Override
+@@ -70,6 +71,11 @@ public class AutoExpandingBufferReadTransport extends TEndpointTransport {
+   @Override
+   public final void consumeBuffer(int len) {
+     pos += len;
++    if (remainingMessageSize >= len) {
++      remainingMessageSize -= len;
++    } else {
++      remainingMessageSize = 0;
++    }
+   }
+ 
+   @Override
+diff --git a/lib/java/src/main/java/org/apache/thrift/transport/TMemoryInputTransport.java b/lib/java/src/main/java/org/apache/thrift/transport/TMemoryInputTransport.java
+index 375e2b72a..2fff0dacc 100644
+--- a/lib/java/src/main/java/org/apache/thrift/transport/TMemoryInputTransport.java
++++ b/lib/java/src/main/java/org/apache/thrift/transport/TMemoryInputTransport.java
+@@ -96,7 +96,6 @@ public final class TMemoryInputTransport extends TEndpointTransport {
+     if (amtToRead > 0) {
+       System.arraycopy(buf_, pos_, buf, off, amtToRead);
+       consumeBuffer(amtToRead);
+-      countConsumedMessageBytes(amtToRead);
+     }
+     return amtToRead;
+   }
+@@ -119,7 +118,13 @@ public final class TMemoryInputTransport extends TEndpointTransport {
+     return endPos_ - pos_;
+   }
+ 
++  @Override
+   public void consumeBuffer(int len) {
+     pos_ += len;
++    if (remainingMessageSize >= len) {
++      remainingMessageSize -= len;
++    } else {
++      remainingMessageSize = 0;
++    }
+   }
+ }
+diff --git a/lib/java/src/test/java/org/apache/thrift/protocol/TestMessageSizeLimits.java b/lib/java/src/test/java/org/apache/thrift/protocol/TestMessageSizeLimits.java
+new file mode 100644
+index 000000000..ab12a0f70
+--- /dev/null
++++ b/lib/java/src/test/java/org/apache/thrift/protocol/TestMessageSizeLimits.java
+@@ -0,0 +1,196 @@
++/*
++ * Licensed to the Apache Software Foundation (ASF) under one
++ * or more contributor license agreements. See the NOTICE file
++ * distributed with this work for additional information
++ * regarding copyright ownership. The ASF licenses this file
++ * to you under the Apache License, Version 2.0 (the
++ * "License"); you may not use this file except in compliance
++ * with the License. You may obtain a copy of the License at
++ *
++ *   http://www.apache.org/licenses/LICENSE-2.0
++ *
++ * Unless required by applicable law or agreed to in writing,
++ * software distributed under the License is distributed on an
++ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
++ * KIND, either express or implied. See the License for the
++ * specific language governing permissions and limitations
++ * under the License.
++ */
++package org.apache.thrift.protocol;
++
++import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
++import static org.junit.jupiter.api.Assertions.assertThrows;
++
++import java.util.Arrays;
++import org.apache.thrift.TConfiguration;
++import org.apache.thrift.transport.AutoExpandingBufferReadTransport;
++import org.apache.thrift.transport.TMemoryInputTransport;
++import org.apache.thrift.transport.TTransportException;
++import org.junit.jupiter.api.Test;
++
++/**
++ * Tests that message size limits are enforced in the fast-path buffer reads of
++ * TBinaryProtocol/TCompactProtocol and that consumeBuffer() correctly tracks consumed bytes.
++ */
++public class TestMessageSizeLimits {
++
++  /** Build TBinaryProtocol-encoded bytes for a string: 4-byte big-endian length + raw bytes. */
++  private byte[] encodeBinaryString(String s) {
++    byte[] data = s.getBytes(java.nio.charset.StandardCharsets.UTF_8);
++    byte[] out = new byte[4 + data.length];
++    int len = data.length;
++    out[0] = (byte) (len >> 24);
++    out[1] = (byte) (len >> 16);
++    out[2] = (byte) (len >> 8);
++    out[3] = (byte) len;
++    System.arraycopy(data, 0, out, 4, data.length);
++    return out;
++  }
++
++  /**
++   * Build TCompactProtocol-encoded bytes for a string: varint length + raw bytes. Assumes length <
++   * 128 so it fits in one varint byte.
++   */
++  private byte[] encodeCompactString(String s) {
++    byte[] data = s.getBytes(java.nio.charset.StandardCharsets.UTF_8);
++    assert data.length < 128 : "test helper only handles single-byte varints";
++    byte[] out = new byte[1 + data.length];
++    out[0] = (byte) data.length;
++    System.arraycopy(data, 0, out, 1, data.length);
++    return out;
++  }
++
++  private static String repeat(char c, int n) {
++    char[] chars = new char[n];
++    Arrays.fill(chars, c);
++    return new String(chars);
++  }
++
++  @Test
++  public void testBinaryProtocol_stringLengthLimitEnforcedInFastPath() throws Exception {
++    // 100-char string encoded for TBinaryProtocol - all bytes in transport so fast path fires
++    byte[] buf = encodeBinaryString(repeat('A', 100));
++    TMemoryInputTransport transport = new TMemoryInputTransport(buf);
++
++    // Protocol limited to 10 bytes per string
++    TBinaryProtocol proto = new TBinaryProtocol(transport, 10L, -1L, false, true);
++
++    assertThrows(
++        TProtocolException.class,
++        proto::readString,
++        "stringLengthLimit must be enforced even when the fast path is taken");
++  }
++
++  @Test
++  public void testBinaryProtocol_stringLengthLimitAllowsValidString() throws Exception {
++    byte[] buf = encodeBinaryString("Hello");
++    TMemoryInputTransport transport = new TMemoryInputTransport(buf);
++
++    TBinaryProtocol proto = new TBinaryProtocol(transport, 10L, -1L, false, true);
++
++    assertDoesNotThrow(
++        proto::readString, "string within stringLengthLimit must be readable via fast path");
++  }
++
++  @Test
++  public void testCompactProtocol_stringLengthLimitEnforcedInFastPath() throws Exception {
++    byte[] buf = encodeCompactString(repeat('A', 100));
++    TMemoryInputTransport transport = new TMemoryInputTransport(buf);
++
++    TCompactProtocol proto = new TCompactProtocol(transport, 10L, -1L);
++
++    assertThrows(
++        TProtocolException.class,
++        proto::readString,
++        "TCompactProtocol stringLengthLimit must reject oversized strings in fast path");
++  }
++
++  @Test
++  public void testConsumeBuffer_decrementsRemainingMessageSize() throws Exception {
++    // 20-byte transport; updateKnownMessageSize sets remainingMessageSize = 20
++    byte[] buf = new byte[20];
++    TMemoryInputTransport transport = new TMemoryInputTransport(buf);
++
++    transport.consumeBuffer(15);
++
++    // 5 bytes remain; requesting 5 must succeed
++    assertDoesNotThrow(() -> transport.checkReadBytesAvailable(5));
++
++    // requesting 6 must fail
++    assertThrows(
++        TTransportException.class,
++        () -> transport.checkReadBytesAvailable(6),
++        "checkReadBytesAvailable must reflect bytes consumed via consumeBuffer");
++  }
++
++  @Test
++  public void testBinaryProtocol_fastPathReadsDrainRemainingMessageSize() throws Exception {
++    // 10 i32 values = 40 bytes; maxMessageSize exactly 40
++    byte[] buf = new byte[40];
++    TConfiguration config = TConfiguration.custom().setMaxMessageSize(40).build();
++    TMemoryInputTransport transport = new TMemoryInputTransport(config, buf);
++    TBinaryProtocol proto = new TBinaryProtocol(transport);
++
++    // Reading 8 i32 values via fast path consumes 32 bytes
++    for (int i = 0; i < 8; i++) {
++      proto.readI32();
++    }
++
++    // 8 bytes remain — requesting exactly 8 must succeed
++    assertDoesNotThrow(
++        () -> transport.checkReadBytesAvailable(8),
++        "8 bytes should still be available after 32 consumed via fast path");
++
++    // requesting 9 must fail — size limit is properly tracked
++    assertThrows(
++        TTransportException.class,
++        () -> transport.checkReadBytesAvailable(9),
++        "fast-path reads must decrement remaining message size so limits can be enforced");
++  }
++
++  @Test
++  public void testRead_doesNotDoubleCountConsumedBytes() throws Exception {
++    // If read() double-counted, consuming 10 bytes via read() on a 20-byte transport
++    // would wrongly decrement remainingMessageSize by 20 instead of 10.
++    byte[] buf = new byte[20];
++    TMemoryInputTransport transport = new TMemoryInputTransport(buf);
++    byte[] dest = new byte[10];
++    transport.read(dest, 0, 10);
++
++    // 10 bytes remain; requesting 10 must succeed
++    assertDoesNotThrow(() -> transport.checkReadBytesAvailable(10));
++
++    // requesting 11 must fail
++    assertThrows(
++        TTransportException.class,
++        () -> transport.checkReadBytesAvailable(11),
++        "read() must not double-count consumed bytes after consumeBuffer fix");
++  }
++
++  @Test
++  public void testAutoExpandingBufferReadTransport_fillResetsMessageSizePerFrame()
++      throws Exception {
++    // fill() must reset remainingMessageSize so that consumption across frames on a long-lived
++    // TFastFramedTransport connection does not accumulate toward the per-message limit.
++    TConfiguration config = TConfiguration.custom().setMaxMessageSize(80).build();
++    AutoExpandingBufferReadTransport readBuf = new AutoExpandingBufferReadTransport(config, 100);
++    TMemoryInputTransport source = new TMemoryInputTransport(new byte[200]);
++
++    // Frame 1: fill and consume 70 bytes
++    readBuf.fill(source, 70);
++    readBuf.consumeBuffer(70);
++
++    // Frame 2: fill resets remainingMessageSize to maxMessageSize (80) before new frame
++    readBuf.fill(source, 70);
++    readBuf.consumeBuffer(70);
++
++    // After two frames of 70 bytes each, 10 bytes of budget must still be available
++    assertDoesNotThrow(
++        () -> readBuf.checkReadBytesAvailable(10),
++        "fill() must reset remainingMessageSize so multi-frame connections stay functional");
++    assertThrows(
++        TTransportException.class,
++        () -> readBuf.checkReadBytesAvailable(11),
++        "remaining budget after fill-reset and 70-byte consume should be exactly 10");
++  }
++}
diff --git a/meta-oe/recipes-connectivity/thrift/thrift_0.22.0.bb b/meta-oe/recipes-connectivity/thrift/thrift_0.22.0.bb
index b5dee9bd00..ad4e841d7b 100644
--- a/meta-oe/recipes-connectivity/thrift/thrift_0.22.0.bb
+++ b/meta-oe/recipes-connectivity/thrift/thrift_0.22.0.bb
@@ -18,6 +18,7 @@ SRC_URI = "https://downloads.apache.org/${BPN}/${PV}/${BP}.tar.gz \
            file://CVE-2026-48144.patch \
            file://CVE-2026-58389.patch \
            file://CVE-2026-41608.patch \
+           file://CVE-2026-45112.patch \
            "
 SRC_URI[sha256sum] = "794a0e455787960d9f27ab92c38e34da27e8deeda7a5db0e59dc64a00df8a1e5"
 
