File CVE-2024-45339.patch of Package google-osconfig-agent.37524

diff -Nru vendor.orig/github.com/golang/glog/glog_file.go vendor/github.com/golang/glog/glog_file.go
--- vendor.orig/github.com/golang/glog/glog_file.go	2025-01-27 09:02:41.000000000 +0100
+++ vendor/github.com/golang/glog/glog_file.go	2025-02-17 10:28:28.777320262 +0100
@@ -116,32 +116,53 @@
 // contains tag ("INFO", "FATAL", etc.) and t.  If the file is created
 // successfully, create also attempts to update the symlink for that tag, ignoring
 // errors.
-func create(tag string, t time.Time) (f *os.File, filename string, err error) {
+func create(tag string, t time.Time, dir string) (f *os.File, filename string, err error) {
+	if dir != "" {
+		f, name, err := createInDir(dir, tag, t)
+		if err == nil {
+			return f, name, err
+		}
+		return nil, "", fmt.Errorf("log: cannot create log: %v", err)
+	}
+
 	onceLogDirs.Do(createLogDirs)
 	if len(logDirs) == 0 {
 		return nil, "", errors.New("log: no log dirs")
 	}
-	name, link := logName(tag, t)
 	var lastErr error
 	for _, dir := range logDirs {
-		fname := filepath.Join(dir, name)
-		f, err := os.Create(fname)
+		f, name, err := createInDir(dir, tag, t)
 		if err == nil {
-			symlink := filepath.Join(dir, link)
-			os.Remove(symlink)        // ignore err
-			os.Symlink(name, symlink) // ignore err
-			if *logLink != "" {
-				lsymlink := filepath.Join(*logLink, link)
-				os.Remove(lsymlink)         // ignore err
-				os.Symlink(fname, lsymlink) // ignore err
-			}
-			return f, fname, nil
+			return f, name, err
 		}
 		lastErr = err
 	}
 	return nil, "", fmt.Errorf("log: cannot create log: %v", lastErr)
 }
 
+func createInDir(dir, tag string, t time.Time) (f *os.File, name string, err error) {
+	name, link := logName(tag, t)
+	fname := filepath.Join(dir, name)
+	// O_EXCL is important here, as it prevents a vulnerability. The general idea is that logs often
+	// live in an insecure directory (like /tmp), so an unprivileged attacker could create fname in
+	// advance as a symlink to a file the logging process can access, but the attacker cannot. O_EXCL
+	// fails the open if it already exists, thus prevent our this code from opening the existing file
+	// the attacker points us to.
+	f, err = os.OpenFile(fname, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0666)
+	if err == nil {
+		symlink := filepath.Join(dir, link)
+		os.Remove(symlink)        // ignore err
+		os.Symlink(name, symlink) // ignore err
+		if *logLink != "" {
+			lsymlink := filepath.Join(*logLink, link)
+			os.Remove(lsymlink)         // ignore err
+			os.Symlink(fname, lsymlink) // ignore err
+		}
+		return f, fname, nil
+	}
+	return nil, "", err
+}
+
 // flushSyncWriter is the interface satisfied by logging destinations.
 type flushSyncWriter interface {
 	Flush() error
@@ -248,6 +269,7 @@
 	names  []string
 	sev    logsink.Severity
 	nbytes uint64 // The number of bytes written to this file
+	madeAt time.Time
 }
 
 func (sb *syncBuffer) Sync() error {
@@ -255,9 +277,14 @@
 }
 
 func (sb *syncBuffer) Write(p []byte) (n int, err error) {
+	// Rotate the file if it is too large, but ensure we only do so,
+	// if rotate doesn't create a conflicting filename.
 	if sb.nbytes+uint64(len(p)) >= MaxSize {
-		if err := sb.rotateFile(time.Now()); err != nil {
-			return 0, err
+		now := timeNow()
+		if now.After(sb.madeAt.Add(1*time.Second)) || now.Second() != sb.madeAt.Second() {
+			if err := sb.rotateFile(now); err != nil {
+				return 0, err
+			}
 		}
 	}
 	n, err = sb.Writer.Write(p)
@@ -275,7 +302,8 @@
 func (sb *syncBuffer) rotateFile(now time.Time) error {
 	var err error
 	pn := "<none>"
-	file, name, err := create(sb.sev.String(), now)
+	file, name, err := create(sb.sev.String(), now, "")
+	sb.madeAt = now
 
 	if sb.file != nil {
 		// The current log file becomes the previous log at the end of
openSUSE Build Service is sponsored by