From 993b3e57eca3035de88cab6883a1eefe4d929e35 Mon Sep 17 00:00:00 2001
From: rcmadhankumar <madhankumar.chellamuthu@suse.com>
Date: Fri, 17 Apr 2026 14:31:21 +0530
Subject: [PATCH 1/2] CVE-2026-33748: Fix git: normalize and validate subdir
 paths --

CVE-2026-33748

Insufficient validation of Git URL fragment subdir components
(<url>#<ref>:<subdir>, docs) may allow access to files outside
the checked-out Git repository root. Possible access is limited
to files on the same mounted filesystem.

Fix: Normalize Git subdir fragments and validate checkout subdir
components so each segment must be a real directory, preventing
traversal and symlink escapes.

Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
(cherry picked from commit 8c994eb561a2646b35352e5663afecd225306214)
(cherry picked from commit f756b3f8aa2f32b0986c1cbb6449a29fe22715d7)

Reference: https://github.com/moby/buildkit/commit/45b038cd0b2ec2d34013ce0f085522276f7ee0d8

Fixes CVE-2026-33748
Fixes bsc#1261078
---
 .../moby/buildkit/source/git/gitsource.go     | 31 ++++++++++++++++++-
 .../moby/buildkit/source/gitidentifier.go     |  5 ++-
 2 files changed, 32 insertions(+), 4 deletions(-)

diff --git a/vendor/github.com/moby/buildkit/source/git/gitsource.go b/vendor/github.com/moby/buildkit/source/git/gitsource.go
index dd35fe55f7..14a21fd65f 100644
--- a/vendor/github.com/moby/buildkit/source/git/gitsource.go
+++ b/vendor/github.com/moby/buildkit/source/git/gitsource.go
@@ -486,7 +486,7 @@ func (gs *gitSourceHandler) Snapshot(ctx context.Context, g session.Group) (out
 		}
 	}()
 
-	subdir := path.Clean(gs.src.Subdir)
+	subdir := path.Join("/", gs.src.Subdir)
 	if subdir == "/" {
 		subdir = "."
 	}
@@ -559,6 +559,11 @@ func (gs *gitSourceHandler) Snapshot(ctx context.Context, g session.Group) (out
 			return nil, errors.Wrapf(err, "failed to checkout remote %s", urlutil.RedactCredentials(gs.src.Remote))
 		}
 		if subdir != "." {
+			subdir = filepath.FromSlash(subdir)
+			if err := validateDirsOnly(cd, subdir); err != nil {
+				return nil, errors.Wrapf(err, "invalid subdir %v", subdir)
+			}
+
 			d, err := os.Open(filepath.Join(cd, subdir))
 			if err != nil {
 				return nil, errors.Wrapf(err, "failed to open subdir %v", subdir)
@@ -761,3 +766,27 @@ func (md cacheRefMetadata) setGitSnapshot(key string) error {
 func (md cacheRefMetadata) setGitRemote(key string) error {
 	return md.SetString(keyGitRemote, key, gitRemoteIndex+key)
 }
+
+// validateDirsOnly checks that the given subpath in the repository
+// only contains directories without any symlinks or files.
+func validateDirsOnly(root string, subpath string) error {
+	rel := filepath.Clean(subpath)
+	rel = strings.TrimPrefix(rel, string(filepath.Separator))
+	if rel == "" || rel == "." {
+		return nil
+	}
+
+	p := root
+	for _, part := range strings.Split(rel, string(filepath.Separator)) {
+		p = filepath.Join(p, part)
+
+		fi, err := os.Lstat(p)
+		if err != nil {
+			return errors.Wrapf(err, "failed to lstat %q", p)
+		}
+		if !fi.IsDir() {
+			return errors.Errorf("git subpath %q contains non-directory %q", subpath, p)
+		}
+	}
+	return nil
+}
diff --git a/vendor/github.com/moby/buildkit/source/gitidentifier.go b/vendor/github.com/moby/buildkit/source/gitidentifier.go
index 6055c94e2f..d72a378f15 100644
--- a/vendor/github.com/moby/buildkit/source/gitidentifier.go
+++ b/vendor/github.com/moby/buildkit/source/gitidentifier.go
@@ -47,9 +47,6 @@ func NewGitIdentifier(remoteURL string) (*GitIdentifier, error) {
 		u.Fragment = ""
 		repo.Remote = u.String()
 	}
-	if sd := path.Clean(repo.Subdir); sd == "/" || sd == "." {
-		repo.Subdir = ""
-	}
 	return &repo, nil
 }
 
@@ -72,5 +69,7 @@ func getRefAndSubdir(fragment string) (ref string, subdir string) {
 	if len(refAndDir) > 1 && len(refAndDir[1]) != 0 {
 		subdir = refAndDir[1]
 	}
+	subdir = path.Join("/", subdir)
+	subdir = strings.TrimPrefix(subdir, "/")
 	return
 }
-- 
2.54.0

