diff --git a/SPECS/telegraf/CVE-2026-56852.patch b/SPECS/telegraf/CVE-2026-56852.patch new file mode 100644 index 00000000000..f1201fc6a84 --- /dev/null +++ b/SPECS/telegraf/CVE-2026-56852.patch @@ -0,0 +1,188 @@ +From b3e20db3aa62a47f1ebcc318ffac6431e1544758 Mon Sep 17 00:00:00 2001 +From: Damien Neil +Date: Tue, 14 Apr 2026 21:46:24 -0400 +Subject: [PATCH] unicode/norm: avoid infinite loop on invalid input + +Invalid characters are given a Properties with a size of 0. + +The nextComposed function can enter an infinite loop when +encountering an invalid character, since it advances +its input by the (possibly 0) character size. + +Rather than finding every place which might assume characters +have a non-zero size, change compInfo to return a size-1 +Properties for invalid characters and use the property flags +to record validity. + +Fixes golang/go#80142 + +Change-Id: Ie0791faefeddc1e8f671b0ed73f29e906a6a6964 +Reviewed-on: https://go-review.googlesource.com/c/text/+/794100 +LUCI-TryBot-Result: golang-scoped@luci-project-accounts.iam.gserviceaccount.com +Auto-Submit: Damien Neil +Reviewed-by: Neal Patel +Reviewed-by: Neal Patel +Signed-off-by: Azure Linux Security Servicing Account +Upstream-reference: https://github.com/golang/text/commit/5ae8e578e495731553eddba11b2d0e86c91a00ce.patch +--- + .../x/text/unicode/norm/forminfo.go | 9 ++++++++- + vendor/golang.org/x/text/unicode/norm/iter.go | 8 ++------ + .../x/text/unicode/norm/normalize.go | 20 +++++++++---------- + 3 files changed, 20 insertions(+), 17 deletions(-) + +diff --git a/vendor/golang.org/x/text/unicode/norm/forminfo.go b/vendor/golang.org/x/text/unicode/norm/forminfo.go +index 487335d1..6596a6bd 100644 +--- a/vendor/golang.org/x/text/unicode/norm/forminfo.go ++++ b/vendor/golang.org/x/text/unicode/norm/forminfo.go +@@ -118,8 +118,12 @@ func (p Properties) BoundaryAfter() bool { + // + // When all 4 bits are zero, the character is inert, meaning it is never + // influenced by normalization. ++// ++// We set flags to 0x80 (high bit 7 unused in quick check data) to indicate an invalid rune. + type qcInfo uint8 + ++func (p Properties) isInvalid() bool { return p.flags == 0x80 } ++ + func (p Properties) isYesC() bool { return p.flags&0x10 == 0 } + func (p Properties) isYesD() bool { return p.flags&0x4 == 0 } + +@@ -241,6 +245,9 @@ func (f Form) PropertiesString(s string) Properties { + // to a Properties. See the comment at the top of the file + // for more information on the format. + func compInfo(v uint16, sz int) Properties { ++ if sz == 0 { ++ return Properties{flags: 0x80, size: 1} ++ } + if v == 0 { + return Properties{size: uint8(sz)} + } else if v >= 0x8000 { +@@ -248,7 +255,7 @@ func compInfo(v uint16, sz int) Properties { + size: uint8(sz), + ccc: uint8(v), + tccc: uint8(v), +- flags: qcInfo(v >> 8), ++ flags: qcInfo(v>>8) & 0x3f, + } + if p.ccc > 0 || p.combinesBackward() { + p.nLead = uint8(p.flags & 0x3) +diff --git a/vendor/golang.org/x/text/unicode/norm/iter.go b/vendor/golang.org/x/text/unicode/norm/iter.go +index 417c6b26..3cc05922 100644 +--- a/vendor/golang.org/x/text/unicode/norm/iter.go ++++ b/vendor/golang.org/x/text/unicode/norm/iter.go +@@ -376,16 +376,12 @@ func nextComposed(i *Iter) []byte { + goto doNorm + } + prevCC = i.info.tccc +- sz := int(i.info.size) +- if sz == 0 { +- sz = 1 // illegal rune: copy byte-by-byte +- } +- p := outp + sz ++ p := outp + int(i.info.size) + if p > len(i.buf) { + break + } + outp = p +- i.p += sz ++ i.p += int(i.info.size) + if i.p >= i.rb.nsrc { + i.setDone() + break +diff --git a/vendor/golang.org/x/text/unicode/norm/normalize.go b/vendor/golang.org/x/text/unicode/norm/normalize.go +index 4747ad07..60b1511c 100644 +--- a/vendor/golang.org/x/text/unicode/norm/normalize.go ++++ b/vendor/golang.org/x/text/unicode/norm/normalize.go +@@ -148,7 +148,7 @@ func (f Form) IsNormalString(s string) bool { + // patched buffer and whether the decomposition is still in progress. + func patchTail(rb *reorderBuffer) bool { + info, p := lastRuneStart(&rb.f, rb.out) +- if p == -1 || info.size == 0 { ++ if p == -1 || info.isInvalid() { + return true + } + end := p + int(info.size) +@@ -225,7 +225,7 @@ func doAppend(rb *reorderBuffer, out []byte, p int) []byte { + } + fd := &rb.f + if doMerge { +- var info Properties ++ info := Properties{flags: 0x80, size: 1} // invalid rune + if p < n { + info = fd.info(src, p) + if !info.BoundaryBefore() || info.nLeadingNonStarters() > 0 { +@@ -235,7 +235,7 @@ func doAppend(rb *reorderBuffer, out []byte, p int) []byte { + p = decomposeSegment(rb, p, true) + } + } +- if info.size == 0 { ++ if info.isInvalid() { + rb.doFlush() + // Append incomplete UTF-8 encoding. + return src.appendSlice(rb.out, p, n) +@@ -314,7 +314,7 @@ func (f *formInfo) quickSpan(src input, i, end int, atEOF bool) (n int, ok bool) + continue + } + info := f.info(src, i) +- if info.size == 0 { ++ if info.isInvalid() { + if atEOF { + // include incomplete runes + return n, true +@@ -379,7 +379,7 @@ func (f Form) firstBoundary(src input, nsrc int) int { + // CGJ insertion points correctly. Luckily it doesn't have to. + for { + info := fd.info(src, i) +- if info.size == 0 { ++ if info.isInvalid() { + return -1 + } + if s := ss.next(info); s != ssSuccess { +@@ -424,7 +424,7 @@ func (f Form) nextBoundary(src input, nsrc int, atEOF bool) int { + } + fd := formTable[f] + info := fd.info(src, 0) +- if info.size == 0 { ++ if info.isInvalid() { + if atEOF { + return 1 + } +@@ -435,7 +435,7 @@ func (f Form) nextBoundary(src input, nsrc int, atEOF bool) int { + + for i := int(info.size); i < nsrc; i += int(info.size) { + info = fd.info(src, i) +- if info.size == 0 { ++ if info.isInvalid() { + if atEOF { + return i + } +@@ -465,7 +465,7 @@ func lastBoundary(fd *formInfo, b []byte) int { + if p == -1 { + return -1 + } +- if info.size == 0 { // ends with incomplete rune ++ if info.isInvalid() { // ends with incomplete rune + if p == 0 { // starts with incomplete rune + return -1 + } +@@ -504,7 +504,7 @@ func lastBoundary(fd *formInfo, b []byte) int { + func decomposeSegment(rb *reorderBuffer, sp int, atEOF bool) int { + // Force one character to be consumed. + info := rb.f.info(rb.src, sp) +- if info.size == 0 { ++ if info.isInvalid() { + return 0 + } + if s := rb.ss.next(info); s == ssStarter { +@@ -528,7 +528,7 @@ func decomposeSegment(rb *reorderBuffer, sp int, atEOF bool) int { + break + } + info = rb.f.info(rb.src, sp) +- if info.size == 0 { ++ if info.isInvalid() { + if !atEOF { + return int(iShortSrc) + } +-- +2.45.4 + diff --git a/SPECS/telegraf/telegraf.spec b/SPECS/telegraf/telegraf.spec index ff532f0f7af..6949b2a406c 100644 --- a/SPECS/telegraf/telegraf.spec +++ b/SPECS/telegraf/telegraf.spec @@ -1,7 +1,7 @@ Summary: agent for collecting, processing, aggregating, and writing metrics. Name: telegraf Version: 1.31.0 -Release: 24%{?dist} +Release: 25%{?dist} License: MIT Vendor: Microsoft Corporation Distribution: Azure Linux @@ -65,6 +65,7 @@ Patch49: CVE-2026-58250.patch Patch50: CVE-2026-58251.patch Patch51: CVE-2026-58252.patch Patch52: CVE-2026-58253.patch +Patch53: CVE-2026-56852.patch BuildRequires: golang BuildRequires: systemd-devel @@ -129,6 +130,9 @@ fi %dir %{_sysconfdir}/%{name}/telegraf.d %changelog +* Tue Jul 28 2026 Azure Linux Security Servicing Account - 1.31.0-25 +- Patch for CVE-2026-56852 + * Sun Jul 12 2026 Azure Linux Security Servicing Account - 1.31.0-24 - Patch for CVE-2026-58253, CVE-2026-58252, CVE-2026-58251, CVE-2026-58250, CVE-2026-58209, CVE-2026-58208, CVE-2026-58207