Skip to content

Commit 3340351

Browse files
azurelinux-securitySumitJenaHCLjykanase
authored
[AutoPR- Security] Patch telegraf for CVE-2026-42151, CVE-2026-41889 [MEDIUM] (microsoft#17221)
Co-authored-by: SumitJenaHCL <v-sumitjena@microsoft.com> Co-authored-by: jykanase <v-jykanase@microsoft.com>
1 parent 9af3bc9 commit 3340351

3 files changed

Lines changed: 222 additions & 1 deletion

File tree

Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
From: Jack Christensen <jack@jackchristensen.com>
2+
Date: Sat, 18 Apr 2026 23:46:10 +0000
3+
Subject: [PATCH] Fix SQL sanitizer bugs with dollar-quoted strings and
4+
placeholder overflow
5+
6+
The simple-protocol SQL sanitizer treated $N found inside PostgreSQL
7+
dollar-quoted strings ($$...$$ and $tag$...$tag$) as placeholders and
8+
substituted them into what PostgreSQL considers literal text. A crafted
9+
arg value could then close the dollar-quote from inside and run
10+
arbitrary SQL (see the new proof-of-concept test in query_test.go).
11+
12+
The lexer now recognizes dollar-quoted strings using PostgreSQL's tag
13+
grammar (from scan.l) and preserves their contents verbatim.
14+
15+
Placeholder numbers are also clamped at MaxInt32 rather than silently
16+
overflowing. Previously "$92233720368547758070" wrapped to -10; if the
17+
wrap had landed on a valid positive index it would have aliased a
18+
different argument.
19+
20+
Adds unit tests, fuzz seeds, and an integration PoC.
21+
22+
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
23+
24+
Upstream Patch Reference: https://github.com/jackc/pgx/commit/60644f84918a8af66d14a4b0d865d4edafd955da.patch
25+
---
26+
.../pgx/v4/internal/sanitize/sanitize.go | 97 +++++++++++++++++--
27+
1 file changed, 89 insertions(+), 8 deletions(-)
28+
29+
diff --git a/vendor/github.com/jackc/pgx/v4/internal/sanitize/sanitize.go b/vendor/github.com/jackc/pgx/v4/internal/sanitize/sanitize.go
30+
index 4c345d50..e6db478c 100644
31+
--- a/vendor/github.com/jackc/pgx/v4/internal/sanitize/sanitize.go
32+
+++ b/vendor/github.com/jackc/pgx/v4/internal/sanitize/sanitize.go
33+
@@ -4,6 +4,7 @@ import (
34+
"bytes"
35+
"encoding/hex"
36+
"fmt"
37+
+ "math"
38+
"strconv"
39+
"strings"
40+
"time"
41+
@@ -100,12 +101,13 @@ func QuoteBytes(buf []byte) string {
42+
}
43+
44+
type sqlLexer struct {
45+
- src string
46+
- start int
47+
- pos int
48+
- nested int // multiline comment nesting level.
49+
- stateFn stateFn
50+
- parts []Part
51+
+ src string
52+
+ start int
53+
+ pos int
54+
+ nested int // multiline comment nesting level.
55+
+ dollarTag string // active tag while inside a dollar-quoted string (may be empty for $$).
56+
+ stateFn stateFn
57+
+ parts []Part
58+
}
59+
60+
type stateFn func(*sqlLexer) stateFn
61+
@@ -135,6 +137,15 @@ func rawState(l *sqlLexer) stateFn {
62+
l.start = l.pos
63+
return placeholderState
64+
}
65+
+ // PostgreSQL dollar-quoted string: $[tag]$...$[tag]$. The $ was
66+
+ // just consumed; try to match the rest of the opening tag.
67+
+ // Without this, placeholders embedded inside dollar-quoted
68+
+ // literals would be incorrectly substituted.
69+
+ if tagLen, ok := scanDollarQuoteTag(l.src[l.pos:]); ok {
70+
+ l.dollarTag = l.src[l.pos : l.pos+tagLen]
71+
+ l.pos += tagLen + 1 // advance past tag and closing '$'
72+
+ return dollarQuoteState
73+
+ }
74+
case '-':
75+
nextRune, width := utf8.DecodeRuneInString(l.src[l.pos:])
76+
if nextRune == '-' {
77+
@@ -217,8 +228,16 @@ func placeholderState(l *sqlLexer) stateFn {
78+
l.pos += width
79+
80+
if '0' <= r && r <= '9' {
81+
- num *= 10
82+
- num += int(r - '0')
83+
+ // Clamp rather than silently wrap on pathological input like
84+
+ // "$92233720368547758070" which would otherwise overflow int and
85+
+ // could land on a valid args index. Any value above MaxInt32 far
86+
+ // exceeds any plausible args length, so Sanitize will correctly
87+
+ // return "insufficient arguments".
88+
+ if num > (math.MaxInt32-9)/10 {
89+
+ num = math.MaxInt32
90+
+ } else {
91+
+ num = num*10 + int(r-'0')
92+
+ }
93+
} else {
94+
l.parts = append(l.parts, num)
95+
l.pos -= width
96+
@@ -228,6 +247,68 @@ func placeholderState(l *sqlLexer) stateFn {
97+
}
98+
}
99+
100+
+// dollarQuoteState consumes the body of a PostgreSQL dollar-quoted string
101+
+// ($[tag]$...$[tag]$). The opening tag (including its terminating '$') has
102+
+// already been consumed.
103+
+func dollarQuoteState(l *sqlLexer) stateFn {
104+
+ closer := "$" + l.dollarTag + "$"
105+
+ idx := strings.Index(l.src[l.pos:], closer)
106+
+ if idx < 0 {
107+
+ // Unterminated — mirror the behavior of other quoted-string states by
108+
+ // consuming the remaining input into the current part and stopping.
109+
+ if len(l.src)-l.start > 0 {
110+
+ l.parts = append(l.parts, l.src[l.start:])
111+
+ l.start = len(l.src)
112+
+ }
113+
+ l.pos = len(l.src)
114+
+ return nil
115+
+ }
116+
+ l.pos += idx + len(closer)
117+
+ l.dollarTag = ""
118+
+ return rawState
119+
+}
120+
+
121+
+// scanDollarQuoteTag checks whether src begins with an optional dollar-quoted
122+
+// string tag followed by a closing '$'. src must point just past the opening
123+
+// '$'. Returns the byte length of the tag (zero for an anonymous $$) and
124+
+// whether a valid tag was found.
125+
+//
126+
+// Tag grammar matches the PostgreSQL lexer (scan.l):
127+
+//
128+
+// dolq_start: [A-Za-z_\x80-\xff]
129+
+// dolq_cont: [A-Za-z0-9_\x80-\xff]
130+
+func scanDollarQuoteTag(src string) (int, bool) {
131+
+ first := true
132+
+ for i := 0; i < len(src); {
133+
+ r, w := utf8.DecodeRuneInString(src[i:])
134+
+ if r == '$' {
135+
+ return i, true
136+
+ }
137+
+ if !isDollarTagRune(r, first) {
138+
+ return 0, false
139+
+ }
140+
+ first = false
141+
+ i += w
142+
+ }
143+
+ return 0, false
144+
+}
145+
+
146+
+func isDollarTagRune(r rune, first bool) bool {
147+
+ switch {
148+
+ case r == '_':
149+
+ return true
150+
+ case 'a' <= r && r <= 'z':
151+
+ return true
152+
+ case 'A' <= r && r <= 'Z':
153+
+ return true
154+
+ case !first && '0' <= r && r <= '9':
155+
+ return true
156+
+ case r >= 0x80 && r != utf8.RuneError:
157+
+ return true
158+
+ }
159+
+ return false
160+
+}
161+
+
162+
func escapeStringState(l *sqlLexer) stateFn {
163+
for {
164+
r, width := utf8.DecodeRuneInString(l.src[l.pos:])
165+
--
166+
2.45.4
167+
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
From 5ccebcdb3f2d8db76b3b559d070d667b903e1358 Mon Sep 17 00:00:00 2001
2+
From: Julien Pivotto <291750+roidelapluie@users.noreply.github.com>
3+
Date: Mon, 27 Apr 2026 12:16:46 +0200
4+
Subject: [PATCH] remote/azuread: use Secret type for OAuth client_secret
5+
6+
The ClientSecret field in OAuthConfig was typed as plain string,
7+
causing it to be exposed in plaintext via the /-/config HTTP endpoint.
8+
Change it to config_util.Secret so Prometheus redacts it as <secret>.
9+
10+
Signed-off-by: Julien Pivotto <291750+roidelapluie@users.noreply.github.com>
11+
12+
Upstream Patch Reference: https://github.com/prometheus/prometheus/commit/5ccebcdb3f2d8db76b3b559d070d667b903e1358.patch
13+
---
14+
.../prometheus/prometheus/storage/remote/azuread/azuread.go | 5 +++--
15+
1 file changed, 3 insertions(+), 2 deletions(-)
16+
17+
diff --git a/vendor/github.com/prometheus/prometheus/storage/remote/azuread/azuread.go b/vendor/github.com/prometheus/prometheus/storage/remote/azuread/azuread.go
18+
index cb4587b0..eb04982a 100644
19+
--- a/vendor/github.com/prometheus/prometheus/storage/remote/azuread/azuread.go
20+
+++ b/vendor/github.com/prometheus/prometheus/storage/remote/azuread/azuread.go
21+
@@ -29,6 +29,7 @@ import (
22+
"github.com/Azure/azure-sdk-for-go/sdk/azcore/policy"
23+
"github.com/Azure/azure-sdk-for-go/sdk/azidentity"
24+
"github.com/google/uuid"
25+
+ config_util "github.com/prometheus/common/config"
26+
)
27+
28+
const (
29+
@@ -55,7 +56,7 @@ type OAuthConfig struct {
30+
ClientID string `yaml:"client_id,omitempty"`
31+
32+
// ClientSecret is the clientSecret of the azure active directory application that is being used to authenticate.
33+
- ClientSecret string `yaml:"client_secret,omitempty"`
34+
+ ClientSecret config_util.Secret `yaml:"client_secret,omitempty"`
35+
36+
// TenantID is the tenantId of the azure active directory application that is being used to authenticate.
37+
TenantID string `yaml:"tenant_id,omitempty"`
38+
@@ -238,7 +239,7 @@ func newManagedIdentityTokenCredential(clientOpts *azcore.ClientOptions, managed
39+
// newOAuthTokenCredential returns new OAuth token credential
40+
func newOAuthTokenCredential(clientOpts *azcore.ClientOptions, oAuthConfig *OAuthConfig) (azcore.TokenCredential, error) {
41+
opts := &azidentity.ClientSecretCredentialOptions{ClientOptions: *clientOpts}
42+
- return azidentity.NewClientSecretCredential(oAuthConfig.TenantID, oAuthConfig.ClientID, oAuthConfig.ClientSecret, opts)
43+
+ return azidentity.NewClientSecretCredential(oAuthConfig.TenantID, oAuthConfig.ClientID, string(oAuthConfig.ClientSecret), opts)
44+
}
45+
46+
// newTokenProvider helps to fetch accessToken for different types of credential. This also takes care of
47+
--
48+
2.45.4
49+

SPECS/telegraf/telegraf.spec

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
Summary: agent for collecting, processing, aggregating, and writing metrics.
22
Name: telegraf
33
Version: 1.31.0
4-
Release: 21%{?dist}
4+
Release: 22%{?dist}
55
License: MIT
66
Vendor: Microsoft Corporation
77
Distribution: Azure Linux
@@ -49,6 +49,8 @@ Patch32: CVE-2026-42506.patch
4949
Patch33: CVE-2026-42508.patch
5050
Patch34: CVE-2026-46597.patch
5151
Patch35: CVE-2026-27136.patch
52+
Patch36: CVE-2026-41889.patch
53+
Patch37: CVE-2026-42151.patch
5254

5355
BuildRequires: golang
5456
BuildRequires: systemd-devel
@@ -113,6 +115,9 @@ fi
113115
%dir %{_sysconfdir}/%{name}/telegraf.d
114116

115117
%changelog
118+
* Thu May 28 2026 Azure Linux Security Servicing Account <azurelinux-security@microsoft.com> - 1.31.0-22
119+
- Patch for CVE-2026-41889, CVE-2026-42151
120+
116121
* Wed May 27 2026 Azure Linux Security Servicing Account <azurelinux-security@microsoft.com> - 1.31.0-21
117122
- Patch for CVE-2026-46597, CVE-2026-42508, CVE-2026-42506, CVE-2026-39834, CVE-2026-39832, CVE-2026-39830, CVE-2026-39829, CVE-2026-39821, CVE-2026-27136
118123

0 commit comments

Comments
 (0)