diff --git a/go.mod b/go.mod index 38a69c68..60f1d38b 100644 --- a/go.mod +++ b/go.mod @@ -2,6 +2,6 @@ module github.com/openshift-sustaining/arc-test-component-b go 1.21 -require github.com/golang/glog v1.2.5 +require github.com/golang/glog v1.2.4 require github.com/google/go-cmp v0.7.0 // indirect diff --git a/go.sum b/go.sum index aad05024..0674bd13 100644 --- a/go.sum +++ b/go.sum @@ -1,4 +1,4 @@ -github.com/golang/glog v1.2.5 h1:DrW6hGnjIhtvhOIiAKT6Psh/Kd/ldepEa81DKeiRJ5I= -github.com/golang/glog v1.2.5/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= +github.com/golang/glog v1.2.4 h1:CNNw5U8lSiiBk7druxtSHHTsRWcxKoac6kZKm2peBBc= +github.com/golang/glog v1.2.4/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= diff --git a/sub-a/go.mod b/sub-a/go.mod index a70b7d02..45c4dc00 100644 --- a/sub-a/go.mod +++ b/sub-a/go.mod @@ -3,7 +3,7 @@ module github.com/openshift-sustaining/arc-test-component-b/sub-a go 1.24 require ( - github.com/golang/glog v1.2.1 + github.com/golang/glog v1.2.4 google.golang.org/grpc v1.65.0 ) diff --git a/sub-a/go.sum b/sub-a/go.sum index d577a4de..bee8e882 100644 --- a/sub-a/go.sum +++ b/sub-a/go.sum @@ -1,5 +1,5 @@ -github.com/golang/glog v1.2.1 h1:OptwRhECazUx5ix5TTWC3EZhsZEHWcYWY4FQHTIubm4= -github.com/golang/glog v1.2.1/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= +github.com/golang/glog v1.2.4 h1:CNNw5U8lSiiBk7druxtSHHTsRWcxKoac6kZKm2peBBc= +github.com/golang/glog v1.2.4/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= diff --git a/sub-a/vendor/github.com/golang/glog/glog.go b/sub-a/vendor/github.com/golang/glog/glog.go index 8c00e737..1b632e07 100644 --- a/sub-a/vendor/github.com/golang/glog/glog.go +++ b/sub-a/vendor/github.com/golang/glog/glog.go @@ -76,7 +76,7 @@ // -log_backtrace_at=gopherflakes.go:234 // A stack trace will be written to the Info log whenever execution // hits one of these statements. (Unlike with -vmodule, the ".go" -// must bepresent.) +// must be present.) // -v=0 // Enable V-leveled logging at the specified level. // -vmodule="" diff --git a/sub-a/vendor/github.com/golang/glog/glog_file.go b/sub-a/vendor/github.com/golang/glog/glog_file.go index a1551dbc..b54bd405 100644 --- a/sub-a/vendor/github.com/golang/glog/glog_file.go +++ b/sub-a/vendor/github.com/golang/glog/glog_file.go @@ -26,7 +26,6 @@ import ( "fmt" "io" "os" - "os/user" "path/filepath" "runtime" "strings" @@ -68,9 +67,8 @@ func init() { host = shortHostname(h) } - current, err := user.Current() - if err == nil { - userName = current.Username + if u := lookupUser(); u != "" { + userName = u } // Sanitize userName since it is used to construct file paths. userName = strings.Map(func(r rune) rune { @@ -118,32 +116,53 @@ var onceLogDirs sync.Once // 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 @@ -160,7 +179,10 @@ var sinks struct { func init() { // Register stderr first: that way if we crash during file-writing at least // the log will have gone somewhere. - logsink.TextSinks = append(logsink.TextSinks, &sinks.stderr, &sinks.file) + if shouldRegisterStderrSink() { + logsink.TextSinks = append(logsink.TextSinks, &sinks.stderr) + } + logsink.TextSinks = append(logsink.TextSinks, &sinks.file) sinks.file.flushChan = make(chan logsink.Severity, 1) go sinks.file.flushDaemon() @@ -247,6 +269,7 @@ type syncBuffer struct { names []string sev logsink.Severity nbytes uint64 // The number of bytes written to this file + madeAt time.Time } func (sb *syncBuffer) Sync() error { @@ -254,9 +277,14 @@ func (sb *syncBuffer) Sync() error { } 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) @@ -274,7 +302,8 @@ const footer = "\nCONTINUED IN NEXT FILE\n" func (sb *syncBuffer) rotateFile(now time.Time) error { var err error pn := "" - 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 diff --git a/sub-a/vendor/github.com/golang/glog/glog_file_nonwindows.go b/sub-a/vendor/github.com/golang/glog/glog_file_nonwindows.go new file mode 100644 index 00000000..a0089ba4 --- /dev/null +++ b/sub-a/vendor/github.com/golang/glog/glog_file_nonwindows.go @@ -0,0 +1,19 @@ +//go:build !windows + +package glog + +import "os/user" + +// shouldRegisterStderrSink determines whether we should register a log sink that writes to stderr. +// Today, this always returns true on non-Windows platforms, as it specifically checks for a +// condition that is only present on Windows. +func shouldRegisterStderrSink() bool { + return true +} + +func lookupUser() string { + if current, err := user.Current(); err == nil { + return current.Username + } + return "" +} diff --git a/sub-a/vendor/github.com/golang/glog/glog_file_windows.go b/sub-a/vendor/github.com/golang/glog/glog_file_windows.go new file mode 100644 index 00000000..2f032e19 --- /dev/null +++ b/sub-a/vendor/github.com/golang/glog/glog_file_windows.go @@ -0,0 +1,43 @@ +//go:build windows + +package glog + +import ( + "os" + "syscall" +) + +// shouldRegisterStderrSink determines whether we should register a log sink that writes to stderr. +// Today, this checks if stderr is "valid", in that it maps to a non-NULL Handle. +// Windows Services are spawned without Stdout and Stderr, so any attempt to use them equates to +// referencing an invalid file Handle. +// os.Stderr's FD is derived from a call to `syscall.GetStdHandle(syscall.STD_ERROR_HANDLE)`. +// Documentation[1] for the GetStdHandle function indicates the return value may be NULL if the +// application lacks the standard handle, so consider Stderr valid if its FD is non-NULL. +// [1]: https://learn.microsoft.com/en-us/windows/console/getstdhandle +func shouldRegisterStderrSink() bool { + return os.Stderr.Fd() != 0 +} + +// This follows the logic in the standard library's user.Current() function, except +// that it leaves out the potentially expensive calls required to look up the user's +// display name in Active Directory. +func lookupUser() string { + token, err := syscall.OpenCurrentProcessToken() + if err != nil { + return "" + } + defer token.Close() + tokenUser, err := token.GetTokenUser() + if err != nil { + return "" + } + username, _, accountType, err := tokenUser.User.Sid.LookupAccount("") + if err != nil { + return "" + } + if accountType != syscall.SidTypeUser { + return "" + } + return username +} diff --git a/sub-a/vendor/modules.txt b/sub-a/vendor/modules.txt index af1835fe..1b12718a 100644 --- a/sub-a/vendor/modules.txt +++ b/sub-a/vendor/modules.txt @@ -1,4 +1,4 @@ -# github.com/golang/glog v1.2.1 +# github.com/golang/glog v1.2.4 ## explicit; go 1.19 github.com/golang/glog github.com/golang/glog/internal/logsink diff --git a/sub-b/go.mod b/sub-b/go.mod index 204b0b87..8ac1532e 100644 --- a/sub-b/go.mod +++ b/sub-b/go.mod @@ -2,6 +2,6 @@ module github.com/openshift-sustaining/arc-test-component-b/sub-b go 1.21 -require github.com/golang/glog v1.2.5 +require github.com/golang/glog v1.2.4 require github.com/google/go-cmp v0.7.0 // indirect diff --git a/sub-b/go.sum b/sub-b/go.sum index aad05024..0674bd13 100644 --- a/sub-b/go.sum +++ b/sub-b/go.sum @@ -1,4 +1,4 @@ -github.com/golang/glog v1.2.5 h1:DrW6hGnjIhtvhOIiAKT6Psh/Kd/ldepEa81DKeiRJ5I= -github.com/golang/glog v1.2.5/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= +github.com/golang/glog v1.2.4 h1:CNNw5U8lSiiBk7druxtSHHTsRWcxKoac6kZKm2peBBc= +github.com/golang/glog v1.2.4/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= diff --git a/vendor/github.com/golang/glog/glog.go b/vendor/github.com/golang/glog/glog.go index c8bebc3b..1b632e07 100644 --- a/vendor/github.com/golang/glog/glog.go +++ b/vendor/github.com/golang/glog/glog.go @@ -238,8 +238,6 @@ func ctxlogf(ctx context.Context, depth int, severity logsink.Severity, verbose metaPool.Put(metai) } -var sinkErrOnce sync.Once - func sinkf(meta *logsink.Meta, format string, args ...any) { meta.Depth++ n, err := logsink.Printf(meta, format, args...) @@ -249,20 +247,9 @@ func sinkf(meta *logsink.Meta, format string, args ...any) { } if err != nil { - // Best-effort to generate a reasonable Fatalf-like - // error message in all sinks that are still here for - // the first goroutine that comes here and terminate - // the process. - sinkErrOnce.Do(func() { - m := &logsink.Meta{} - m.Time = timeNow() - m.Severity = logsink.Fatal - m.Thread = int64(pid) - _, m.File, m.Line, _ = runtime.Caller(0) - format, args := appendBacktrace(1, "log: exiting because of error writing previous log to sinks: %v", []any{err}) - logsink.Printf(m, format, args...) - flushAndAbort() - }) + logsink.Printf(meta, "glog: exiting because of error: %s", err) + sinks.file.Flush() + os.Exit(2) } } @@ -655,10 +642,6 @@ func ErrorContextDepthf(ctx context.Context, depth int, format string, args ...a func ctxfatalf(ctx context.Context, depth int, format string, args ...any) { ctxlogf(ctx, depth+1, logsink.Fatal, false, withStack, format, args...) - flushAndAbort() -} - -func flushAndAbort() { sinks.file.Flush() err := abortProcess() // Should not return. diff --git a/vendor/modules.txt b/vendor/modules.txt index 53501c00..3dda3cdb 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -1,4 +1,4 @@ -# github.com/golang/glog v1.2.5 +# github.com/golang/glog v1.2.4 ## explicit; go 1.19 github.com/golang/glog github.com/golang/glog/internal/logsink