Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package amazon-ssm-agent for
openSUSE:Factory checked in at 2026-05-13 17:20:41
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/amazon-ssm-agent (Old)
and /work/SRC/openSUSE:Factory/.amazon-ssm-agent.new.1966 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "amazon-ssm-agent"
Wed May 13 17:20:41 2026 rev:43 rq:1352892 version:3.3.4268.0
Changes:
--------
--- /work/SRC/openSUSE:Factory/amazon-ssm-agent/amazon-ssm-agent.changes
2026-04-23 17:13:58.611798380 +0200
+++
/work/SRC/openSUSE:Factory/.amazon-ssm-agent.new.1966/amazon-ssm-agent.changes
2026-05-13 17:22:13.090457302 +0200
@@ -1,0 +2,7 @@
+Tue May 12 10:44:03 UTC 2026 - John Paul Adrian Glaubitz
<[email protected]>
+
+- Add CVE-2026-41506.patch to fix HTTP authentication credential
+ leak when following redirects during smart-HTTP clone and fetch
+ operations (bsc#1264952, CVE-2026-41506)
+
+-------------------------------------------------------------------
New:
----
CVE-2026-41506.patch
----------(New B)----------
New:
- Add CVE-2026-41506.patch to fix HTTP authentication credential
leak when following redirects during smart-HTTP clone and fetch
----------(New E)----------
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ amazon-ssm-agent.spec ++++++
--- /var/tmp/diff_new_pack.46Ib14/_old 2026-05-13 17:22:14.538517362 +0200
+++ /var/tmp/diff_new_pack.46Ib14/_new 2026-05-13 17:22:14.554518026 +0200
@@ -25,6 +25,9 @@
URL: https://github.com/aws/amazon-ssm-agent
Source0:
https://github.com/aws/amazon-ssm-agent/archive/%{version}.tar.gz#/%{name}-%{version}.tar.gz
Source1: amazon-ssm-agent.tmpfiles
+# PATCH-FIX-UPSTREAM - HTTP authentication credential leak when following
redirects during smart-HTTP clone and fetch operations
+# Partial patch taken from
https://github.com/go-git/go-git/pull/2004/changes/bcd20a9c525826081262a06a9ed9c3167abfcd53
+Patch0: CVE-2026-41506.patch
BuildRequires: golang(API) >= 1.25.8
BuildRequires: pkgconfig(systemd)
Requires: systemd
@@ -96,6 +99,9 @@
%prep
%setup -q
+pushd vendor/github.com/go-git/go-git/v5
+%patch -P0 -p1
+popd
sed -i -e 's#const[ \s]*Version.*#const Version = "%{version}"#g'
agent/version/version.go
sed -i 's#/bin/#/sbin/#' packaging/linux/amazon-ssm-agent.service
sed -i 's#var defaultWorkerPath = "/usr/bin/"#var defaultWorkerPath =
"/usr/sbin/"#' agent/appconfig/constants_unix.go
++++++ CVE-2026-41506.patch ++++++
>From 013775d696e074e3d8c030c34af0cecca2e86c8c Mon Sep 17 00:00:00 2001
From: Paulo Gomes <[email protected]>
Date: Thu, 16 Apr 2026 12:14:28 +0100
Subject: [PATCH] plumbing: transport/http, Add support for followRedirects
policy Back-port from #1997.
Signed-off-by: Paulo Gomes <[email protected]>
---
plumbing/transport/http/common.go | 168 ++++++++++++++++++++++++++----
1 file changed, 147 insertions(+), 21 deletions(-)
diff --git a/plumbing/transport/http/common.go
b/plumbing/transport/http/common.go
index 5dd2e311..83f93f16 100644
--- a/plumbing/transport/http/common.go
+++ b/plumbing/transport/http/common.go
@@ -7,7 +7,6 @@ import (
"crypto/tls"
"crypto/x509"
"fmt"
- "net"
"net/http"
"net/url"
"reflect"
@@ -24,6 +23,33 @@ import (
"github.com/go-git/go-git/v5/utils/ioutil"
)
+type contextKey int
+
+const initialRequestKey contextKey = iota
+
+// RedirectPolicy controls how the HTTP transport follows redirects.
+//
+// The values mirror Git's http.followRedirects config:
+// "true" follows redirects for all requests, "false" treats redirects as
+// errors, and "initial" follows redirects only for the initial
+// /info/refs discovery request. The zero value defaults to "initial".
+type RedirectPolicy string
+
+const (
+ FollowInitialRedirects RedirectPolicy = "initial"
+ FollowRedirects RedirectPolicy = "true"
+ NoFollowRedirects RedirectPolicy = "false"
+)
+
+func withInitialRequest(ctx context.Context) context.Context {
+ return context.WithValue(ctx, initialRequestKey, true)
+}
+
+func isInitialRequest(req *http.Request) bool {
+ v, _ := req.Context().Value(initialRequestKey).(bool)
+ return v
+}
+
// it requires a bytes.Buffer, because we need to know the length
func applyHeadersToRequest(req *http.Request, content *bytes.Buffer, host
string, requestType string) {
req.Header.Add("User-Agent", capability.DefaultAgent())
@@ -54,12 +80,15 @@ func advertisedReferences(ctx context.Context, s *session,
serviceName string) (
s.ApplyAuthToRequest(req)
applyHeadersToRequest(req, nil, s.endpoint.Host, serviceName)
- res, err := s.client.Do(req.WithContext(ctx))
+ res, err := s.client.Do(req.WithContext(withInitialRequest(ctx)))
if err != nil {
return nil, err
}
- s.ModifyEndpointIfRedirect(res)
+ if err := s.ModifyEndpointIfRedirect(res); err != nil {
+ _ = res.Body.Close()
+ return nil, err
+ }
defer ioutil.CheckClose(res.Body, &err)
if err = NewErr(res); err != nil {
@@ -96,6 +125,7 @@ type client struct {
client *http.Client
transports *lru.Cache
mutex sync.RWMutex
+ follow RedirectPolicy
}
// ClientOptions holds user configurable options for the client.
@@ -106,6 +136,11 @@ type ClientOptions struct {
// size, will result in the least recently used transport getting
deleted
// before the provided transport is added to the cache.
CacheMaxEntries int
+
+ // RedirectPolicy controls redirect handling. Supported values are
+ // "true", "false", and "initial". The zero value defaults to
+ // "initial", matching Git's http.followRedirects default.
+ RedirectPolicy RedirectPolicy
}
var (
@@ -150,12 +185,16 @@ func NewClientWithOptions(c *http.Client, opts
*ClientOptions) transport.Transpo
}
cl := &client{
client: c,
+ follow: FollowInitialRedirects,
}
if opts != nil {
if opts.CacheMaxEntries > 0 {
cl.transports = lru.New(opts.CacheMaxEntries)
}
+ if opts.RedirectPolicy != "" {
+ cl.follow = opts.RedirectPolicy
+ }
}
return cl
}
@@ -289,14 +328,9 @@ func newSession(c *client, ep *transport.Endpoint, auth
transport.AuthMethod) (*
}
}
- httpClient = &http.Client{
- Transport: transport,
- CheckRedirect: c.client.CheckRedirect,
- Jar: c.client.Jar,
- Timeout: c.client.Timeout,
- }
+ httpClient = c.cloneHTTPClient(transport)
} else {
- httpClient = c.client
+ httpClient = c.cloneHTTPClient(c.client.Transport)
}
s := &session{
@@ -324,30 +358,122 @@ func (s *session) ApplyAuthToRequest(req *http.Request) {
s.auth.SetAuth(req)
}
-func (s *session) ModifyEndpointIfRedirect(res *http.Response) {
+func (s *session) ModifyEndpointIfRedirect(res *http.Response) error {
if res.Request == nil {
- return
+ return nil
+ }
+ if s.endpoint == nil {
+ return fmt.Errorf("http redirect: nil endpoint")
}
r := res.Request
if !strings.HasSuffix(r.URL.Path, infoRefsPath) {
- return
+ return fmt.Errorf("http redirect: target %q does not end with
%s", r.URL.Path, infoRefsPath)
+ }
+ if r.URL.Scheme != "http" && r.URL.Scheme != "https" {
+ return fmt.Errorf("http redirect: unsupported scheme %q",
r.URL.Scheme)
+ }
+ if r.URL.Scheme != s.endpoint.Protocol &&
+ !(s.endpoint.Protocol == "http" && r.URL.Scheme == "https") {
+ return fmt.Errorf("http redirect: changes scheme from %q to
%q", s.endpoint.Protocol, r.URL.Scheme)
}
- h, p, err := net.SplitHostPort(r.URL.Host)
+ host := endpointHost(r.URL.Hostname())
+ port, err := endpointPort(r.URL.Port())
if err != nil {
- h = r.URL.Host
+ return err
}
- if p != "" {
- port, err := strconv.Atoi(p)
- if err == nil {
- s.endpoint.Port = port
- }
+
+ if host != s.endpoint.Host || effectivePort(r.URL.Scheme, port) !=
effectivePort(s.endpoint.Protocol, s.endpoint.Port) {
+ s.endpoint.User = ""
+ s.endpoint.Password = ""
+ s.auth = nil
}
- s.endpoint.Host = h
+
+ s.endpoint.Host = host
+ s.endpoint.Port = port
s.endpoint.Protocol = r.URL.Scheme
s.endpoint.Path = r.URL.Path[:len(r.URL.Path)-len(infoRefsPath)]
+ return nil
+}
+
+func endpointHost(host string) string {
+ if strings.Contains(host, ":") {
+ return "[" + host + "]"
+ }
+
+ return host
+}
+
+func endpointPort(port string) (int, error) {
+ if port == "" {
+ return 0, nil
+ }
+
+ parsed, err := strconv.Atoi(port)
+ if err != nil {
+ return 0, fmt.Errorf("http redirect: invalid port %q", port)
+ }
+
+ return parsed, nil
+}
+
+func effectivePort(scheme string, port int) int {
+ if port != 0 {
+ return port
+ }
+
+ switch strings.ToLower(scheme) {
+ case "http":
+ return 80
+ case "https":
+ return 443
+ default:
+ return 0
+ }
+}
+
+func (c *client) cloneHTTPClient(transport http.RoundTripper) *http.Client {
+ return &http.Client{
+ Transport: transport,
+ CheckRedirect: wrapCheckRedirect(c.follow,
c.client.CheckRedirect),
+ Jar: c.client.Jar,
+ Timeout: c.client.Timeout,
+ }
+}
+
+func wrapCheckRedirect(policy RedirectPolicy, next func(*http.Request,
[]*http.Request) error) func(*http.Request, []*http.Request) error {
+ return func(req *http.Request, via []*http.Request) error {
+ if err := checkRedirect(req, via, policy); err != nil {
+ return err
+ }
+ if next != nil {
+ return next(req, via)
+ }
+ return nil
+ }
+}
+
+func checkRedirect(req *http.Request, via []*http.Request, policy
RedirectPolicy) error {
+ switch policy {
+ case FollowRedirects:
+ case NoFollowRedirects:
+ return fmt.Errorf("http redirect: redirects disabled to %s",
req.URL)
+ case "", FollowInitialRedirects:
+ if !isInitialRequest(req) {
+ return fmt.Errorf("http redirect: redirect on
non-initial request to %s", req.URL)
+ }
+ default:
+ return fmt.Errorf("http redirect: invalid redirect policy %q",
policy)
+ }
+ if req.URL.Scheme != "http" && req.URL.Scheme != "https" {
+ return fmt.Errorf("http redirect: unsupported scheme %q",
req.URL.Scheme)
+ }
+ if len(via) >= 10 {
+ return fmt.Errorf("http redirect: too many redirects")
+ }
+ return nil
}
func (*session) Close() error {
--
2.54.0