106 lines
3.7 KiB
Diff
106 lines
3.7 KiB
Diff
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
|