[meta-virtualization][scarthgap][PATCH] go-logrus: Fix CVE-2025-65637

"Hetvi Thakar -X (hthakar - E INFOCHIPS PRIVATE LIMITED at Cisco)" <[email protected]>
Newsgroups org.yoctoproject.lists.meta-virtualization
Message-ID <[email protected]>
From: Hetvi Thakar <[email protected]>

The upstream fix cited by [3] was reverted and later reapplied in [1].
Apply its required correction [2] to avoid a Writer panic.

[1] https://github.com/sirupsen/logrus/commit/f9291a534cac1466d26414fd9e326381cd64ecef
[2] https://github.com/sirupsen/logrus/commit/d40e25cd45ed9c6b2b66e6b97573a0413e4c23bd
[3] https://github.com/advisories/GHSA-4f99-4q7p-p3gh

Signed-off-by: Hetvi Thakar <[email protected]>
---
 .../go/go-logrus/CVE-2025-65637_p1.patch      |  97 ++++++++++++
 .../go/go-logrus/CVE-2025-65637_p2.patch      | 148 ++++++++++++++++++
 recipes-devtools/go/go-logrus_git.bb          |   5 +-
 3 files changed, 249 insertions(+), 1 deletion(-)
 create mode 100644 recipes-devtools/go/go-logrus/CVE-2025-65637_p1.patch
 create mode 100644 recipes-devtools/go/go-logrus/CVE-2025-65637_p2.patch

diff --git a/recipes-devtools/go/go-logrus/CVE-2025-65637_p1.patch b/recipes-devtools/go/go-logrus/CVE-2025-65637_p1.patch
new file mode 100644
index 00000000..309f6420
--- /dev/null
+++ b/recipes-devtools/go/go-logrus/CVE-2025-65637_p1.patch
@@ -0,0 +1,97 @@
+From 2d0e297057a0ade6c17e0e84a9927840bd2b6d7f Mon Sep 17 00:00:00 2001
+From: Simon Eskildsen <[email protected]>
+Date: Sun, 21 May 2023 08:59:03 -0400
+Subject: [PATCH 1/2] Revert "Revert "Merge pull request #1376 from
+ ozfive/master""
+
+This reverts commit 352781de903c9dc639752a3ac08148132746e180.
+
+CVE: CVE-2025-65637
+Upstream-Status: Backport [https://github.com/sirupsen/logrus/commit/f9291a534cac1466d26414fd9e326381cd64ecef]
+
+Backport Changes:
+- Applied the WriterLevel and writerScanner changes to the Logger receiver
+  because Logrus 0.11.0 does not provide the corresponding Entry APIs.
+- Omitted comments for the absent Entry.Writer and Entry.WriterLevel methods.
+
+(cherry picked from commit f9291a534cac1466d26414fd9e326381cd64ecef)
+Signed-off-by: Hetvi Thakar <[email protected]>
+---
+ writer.go | 32 +++++++++++++++++++++++++++++++-
+ 1 file changed, 31 insertions(+), 1 deletion(-)
+
+diff --git a/writer.go b/writer.go
+index f74d2aa..6f7cefd 100644
+--- a/writer.go
++++ b/writer.go
+@@ -4,6 +4,7 @@ import (
+ 	"bufio"
+ 	"io"
+ 	"runtime"
++	"strings"
+ )
+ 
+ func (logger *Logger) Writer() *io.PipeWriter {
+@@ -14,6 +15,7 @@ func (logger *Logger) WriterLevel(level Level) *io.PipeWriter {
+ 	reader, writer := io.Pipe()
+ 
+ 	var printFunc func(args ...interface{})
++	// Determine which log function to use based on the specified log level
+ 	switch level {
+ 	case DebugLevel:
+ 		printFunc = logger.Debug
+@@ -31,23 +33,51 @@ func (logger *Logger) WriterLevel(level Level) *io.PipeWriter {
+ 		printFunc = logger.Print
+ 	}
+ 
++	// Start a new goroutine to scan the input and write it to the logger using the specified print function.
++	// It splits the input into chunks of up to 64KB to avoid buffer overflows.
+ 	go logger.writerScanner(reader, printFunc)
++
++	// Set a finalizer function to close the writer when it is garbage collected
+ 	runtime.SetFinalizer(writer, writerFinalizer)
+ 
+ 	return writer
+ }
+ 
++// writerScanner scans the input from the reader and writes it to the logger
+ func (logger *Logger) writerScanner(reader *io.PipeReader, printFunc func(args ...interface{})) {
+ 	scanner := bufio.NewScanner(reader)
++
++	// Set the buffer size to the maximum token size to avoid buffer overflows
++	scanner.Buffer(make([]byte, bufio.MaxScanTokenSize), bufio.MaxScanTokenSize)
++
++	// Define a split function to split the input into chunks of up to 64KB
++	chunkSize := 64 * 1024 // 64KB
++	splitFunc := func(data []byte, atEOF bool) (int, []byte, error) {
++		if len(data) > chunkSize {
++			return chunkSize, data[:chunkSize], nil
++		}
++
++		return len(data), data, nil
++	}
++
++	//Use the custom split function to split the input
++	scanner.Split(splitFunc)
++
++	// Scan the input and write it to the logger using the specified print function
+ 	for scanner.Scan() {
+-		printFunc(scanner.Text())
++		printFunc(strings.TrimRight(scanner.Text(), "\r\n"))
+ 	}
++
++	// If there was an error while scanning the input, log an error
+ 	if err := scanner.Err(); err != nil {
+ 		logger.Errorf("Error while reading from Writer: %s", err)
+ 	}
++
++	// Close the reader when we are done
+ 	reader.Close()
+ }
+ 
++// WriterFinalizer is a finalizer function that closes then given writer when it is garbage collected
+ func writerFinalizer(writer *io.PipeWriter) {
+ 	writer.Close()
+ }
+-- 
+2.35.6
diff --git a/recipes-devtools/go/go-logrus/CVE-2025-65637_p2.patch b/recipes-devtools/go/go-logrus/CVE-2025-65637_p2.patch
new file mode 100644
index 00000000..c43172aa
--- /dev/null
+++ b/recipes-devtools/go/go-logrus/CVE-2025-65637_p2.patch
@@ -0,0 +1,148 @@
+From e381b4e9cc266f5d8fe6bc9b0557ba372f42ec9d Mon Sep 17 00:00:00 2001
+From: Paul Holzinger <[email protected]>
+Date: Wed, 17 May 2023 15:39:49 +0200
+Subject: [PATCH 2/2] fix panic in Writer
+
+Commit 766cfece introduced this bug by defining an incorrect split
+function. First it breaks the old behavior because it never splits at
+newlines now. Second, it causes a panic because it never tells the
+scanner to stop. See the bufio.ScanLines function, something like:
+```
+if atEOF && len(data) == 0 {
+	return 0, nil, nil
+}
+```
+is needed to do that.
+
+This commit fixes it by restoring the old behavior and calling
+bufio.ScanLines but also keep the 64KB check in place to avoid buffering
+for to long.
+
+Two tests are added to ensure it is working as expected.
+
+Fixes #1383
+
+Signed-off-by: Paul Holzinger <[email protected]>
+
+CVE: CVE-2025-65637
+Upstream-Status: Backport [https://github.com/sirupsen/logrus/commit/d40e25cd45ed9c6b2b66e6b97573a0413e4c23bd]
+
+Backport Changes:
+- Adapted the writerScanner receiver from Entry to the Logger API used by
+  Logrus 0.11.0.
+- Created writer_test.go because it is absent in Logrus 0.11.0, adding only
+  the package/import scaffolding needed by the two upstream regression tests.
+- Adapted the tests from Logger.SetOutput to the Logger.Out field provided
+  by Logrus 0.11.0.
+
+(cherry picked from commit d40e25cd45ed9c6b2b66e6b97573a0413e4c23bd)
+Signed-off-by: Hetvi Thakar <[email protected]>
+---
+ writer.go      |  8 +++---
+ writer_test.go | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 74 insertions(+), 4 deletions(-)
+ create mode 100644 writer_test.go
+
+diff --git a/writer.go b/writer.go
+index 6f7cefd..61d13f0 100644
+--- a/writer.go
++++ b/writer.go
+@@ -51,16 +51,16 @@ func (logger *Logger) writerScanner(reader *io.PipeReader, printFunc func(args .
+ 	scanner.Buffer(make([]byte, bufio.MaxScanTokenSize), bufio.MaxScanTokenSize)
+ 
+ 	// Define a split function to split the input into chunks of up to 64KB
+-	chunkSize := 64 * 1024 // 64KB
++	chunkSize := bufio.MaxScanTokenSize // 64KB
+ 	splitFunc := func(data []byte, atEOF bool) (int, []byte, error) {
+-		if len(data) > chunkSize {
++		if len(data) >= chunkSize {
+ 			return chunkSize, data[:chunkSize], nil
+ 		}
+ 
+-		return len(data), data, nil
++		return bufio.ScanLines(data, atEOF)
+ 	}
+ 
+-	//Use the custom split function to split the input
++	// Use the custom split function to split the input
+ 	scanner.Split(splitFunc)
+ 
+ 	// Scan the input and write it to the logger using the specified print function
+diff --git a/writer_test.go b/writer_test.go
+new file mode 100644
+index 0000000..0fe80f9
+--- /dev/null
++++ b/writer_test.go
+@@ -0,0 +1,70 @@
++package logrus_test
++
++import (
++	"bufio"
++	"bytes"
++	"strings"
++	"testing"
++	"time"
++
++	"github.com/sirupsen/logrus"
++	"github.com/stretchr/testify/assert"
++)
++
++func TestWriterSplitNewlines(t *testing.T) {
++	buf := bytes.NewBuffer(nil)
++	logger := logrus.New()
++	logger.Formatter = &logrus.TextFormatter{
++		DisableColors:    true,
++		DisableTimestamp: true,
++	}
++	logger.Out = buf
++	writer := logger.Writer()
++
++	const logNum = 10
++
++	for i := 0; i < logNum; i++ {
++		_, err := writer.Write([]byte("bar\nfoo\n"))
++		assert.NoError(t, err, "writer.Write failed")
++	}
++	writer.Close()
++	// Test is flaky because it writes in another goroutine,
++	// we need to make sure to wait a bit so all write are done.
++	time.Sleep(500 * time.Millisecond)
++
++	lines := strings.Split(strings.TrimRight(buf.String(), "\n"), "\n")
++	assert.Len(t, lines, logNum*2, "logger printed incorrect number of lines")
++}
++
++func TestWriterSplitsMax64KB(t *testing.T) {
++	buf := bytes.NewBuffer(nil)
++	logger := logrus.New()
++	logger.Formatter = &logrus.TextFormatter{
++		DisableColors:    true,
++		DisableTimestamp: true,
++	}
++	logger.Out = buf
++	writer := logger.Writer()
++
++	// write more than 64KB
++	const bigWriteLen = bufio.MaxScanTokenSize + 100
++	output := make([]byte, bigWriteLen)
++	// lets not write zero bytes
++	for i := 0; i < bigWriteLen; i++ {
++		output[i] = 'A'
++	}
++
++	for i := 0; i < 3; i++ {
++		len, err := writer.Write(output)
++		assert.NoError(t, err, "writer.Write failed")
++		assert.Equal(t, bigWriteLen, len, "bytes written")
++	}
++	writer.Close()
++	// Test is flaky because it writes in another goroutine,
++	// we need to make sure to wait a bit so all write are done.
++	time.Sleep(500 * time.Millisecond)
++
++	lines := strings.Split(strings.TrimRight(buf.String(), "\n"), "\n")
++	// we should have 4 lines because we wrote more than 64 KB each time
++	assert.Len(t, lines, 4, "logger printed incorrect number of lines")
++}
+-- 
+2.35.6
diff --git a/recipes-devtools/go/go-logrus_git.bb b/recipes-devtools/go/go-logrus_git.bb
index 1826b893..35ed35dd 100644
--- a/recipes-devtools/go/go-logrus_git.bb
+++ b/recipes-devtools/go/go-logrus_git.bb
@@ -7,7 +7,10 @@ LIC_FILES_CHKSUM = "file://LICENSE;md5=8dadfef729c08ec4e631c4f6fc5d43a0"
 SRCNAME = "logrus"
 
 PKG_NAME = "github.com/sirupsen/${SRCNAME}"
-SRC_URI = "git://${PKG_NAME};branch=master;protocol=https"
+SRC_URI = "git://${PKG_NAME};branch=master;protocol=https \
+           file://CVE-2025-65637_p1.patch \
+           file://CVE-2025-65637_p2.patch \
+          "
 
 SRCREV = "d26492970760ca5d33129d2d799e34be5c4782eb"
 PV = "0.11.0+git"
-- 
2.35.6
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.