Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion LICENSES-AND-NOTICES/SPECS/LICENSES-MAP.md

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions LICENSES-AND-NOTICES/SPECS/data/licenses.json
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@
"byacc",
"ca-certificates",
"cachefilesd",
"caddy",
"cairomm",
"calamares",
"capnproto",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
From ffc4888694c5222e9eddecb461c955d5661aa18c Mon Sep 17 00:00:00 2001
From: Carl George <[email protected]>
Date: Wed, 16 Feb 2022 11:45:03 -0600
Subject: [PATCH 1/2] Disable commands that can alter the binary

---
cmd/commands.go | 45 ---------------------------------------------
1 file changed, 45 deletions(-)

diff --git a/cmd/commands.go b/cmd/commands.go
index 259dd358..31b85a18 100644
--- a/cmd/commands.go
+++ b/cmd/commands.go
@@ -395,51 +395,6 @@ is always printed to stdout.
},
})

- RegisterCommand(Command{
- Name: "upgrade",
- Short: "Upgrade Caddy (EXPERIMENTAL)",
- Long: `
-Downloads an updated Caddy binary with the same modules/plugins at the
-latest versions. EXPERIMENTAL: May be changed or removed.
-`,
- CobraFunc: func(cmd *cobra.Command) {
- cmd.Flags().BoolP("keep-backup", "k", false, "Keep the backed up binary, instead of deleting it")
- cmd.RunE = WrapCommandFuncForCobra(cmdUpgrade)
- },
- })
-
- RegisterCommand(Command{
- Name: "add-package",
- Usage: "<package[@version]...>",
- Short: "Adds Caddy packages (EXPERIMENTAL)",
- Long: `
-Downloads an updated Caddy binary with the specified packages (module/plugin)
-added, with an optional version specified (e.g., "package@version"). Retains
-existing packages. Returns an error if any of the specified packages are already
-included. EXPERIMENTAL: May be changed or removed.
-`,
- CobraFunc: func(cmd *cobra.Command) {
- cmd.Flags().BoolP("keep-backup", "k", false, "Keep the backed up binary, instead of deleting it")
- cmd.RunE = WrapCommandFuncForCobra(cmdAddPackage)
- },
- })
-
- RegisterCommand(Command{
- Name: "remove-package",
- Func: cmdRemovePackage,
- Usage: "<packages...>",
- Short: "Removes Caddy packages (EXPERIMENTAL)",
- Long: `
-Downloads an updated Caddy binaries without the specified packages (module/plugin).
-Returns an error if any of the packages are not included.
-EXPERIMENTAL: May be changed or removed.
-`,
- CobraFunc: func(cmd *cobra.Command) {
- cmd.Flags().BoolP("keep-backup", "k", false, "Keep the backed up binary, instead of deleting it")
- cmd.RunE = WrapCommandFuncForCobra(cmdRemovePackage)
- },
- })
-
defaultFactory.Use(func(rootCmd *cobra.Command) {
rootCmd.AddCommand(caddyCmdToCobra(Command{
Name: "manpage",
--
2.47.1

120 changes: 120 additions & 0 deletions SPECS/caddy/CVE-2024-45339.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
From afd4339ec8682b92eb6bcc870d138106ffd5f58d Mon Sep 17 00:00:00 2001
From: kavyasree <[email protected]>
Date: Fri, 31 Jan 2025 21:16:51 +0530
Subject: [PATCH] Patch CVE-2024-45339

Reference: https://github.com/golang/glog/pull/74

---
vendor/github.com/golang/glog/glog_file.go | 60 ++++++++++++++++------
1 file changed, 44 insertions(+), 16 deletions(-)

diff --git a/vendor/github.com/golang/glog/glog_file.go b/vendor/github.com/golang/glog/glog_file.go
index e7d125c..6d239fa 100644
--- a/vendor/github.com/golang/glog/glog_file.go
+++ b/vendor/github.com/golang/glog/glog_file.go
@@ -118,32 +118,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
@@ -247,6 +268,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 +276,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 +301,8 @@ const footer = "\nCONTINUED IN NEXT FILE\n"
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
--
2.34.1

139 changes: 139 additions & 0 deletions SPECS/caddy/CVE-2025-22869.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
From 041b89a18f81265899e42e6801f830c101a96120 Mon Sep 17 00:00:00 2001
From: Kanishk-Bansal <[email protected]>
Date: Sun, 2 Mar 2025 13:46:00 +0000
Subject: [PATCH] CVE-2025-22869

Upstream Reference : https://github.com/golang/crypto/commit/7292932d45d55c7199324ab0027cc86e8198aa22

ssh: limit the size of the internal packet queue while waiting for KEX

In the SSH protocol, clients and servers execute the key exchange to
generate one-time session keys used for encryption and authentication.
The key exchange is performed initially after the connection is
established and then periodically after a configurable amount of data.
While a key exchange is in progress, we add the received packets to an
internal queue until we receive SSH_MSG_KEXINIT from the other side.
This can result in high memory usage if the other party is slow to
respond to the SSH_MSG_KEXINIT packet, or memory exhaustion if a
malicious client never responds to an SSH_MSG_KEXINIT packet during a
large file transfer.
We now limit the internal queue to 64 packets: this means 2MB with the
typical 32KB packet size.
When the internal queue is full we block further writes until the
pending key exchange is completed or there is a read or write error.

Thanks to Yuichi Watanabe for reporting this issue.

Change-Id: I1ce2214cc16e08b838d4bc346c74c72addafaeec
Reviewed-on: https://go-review.googlesource.com/c/crypto/+/652135
Reviewed-by: Neal Patel <[email protected]>
Auto-Submit: Gopher Robot <[email protected]>
Reviewed-by: Roland Shoemaker <[email protected]>
LUCI-TryBot-Result: Go LUCI <[email protected]>

---
vendor/golang.org/x/crypto/ssh/handshake.go | 47 ++++++++++++++++-----
1 file changed, 37 insertions(+), 10 deletions(-)

diff --git a/vendor/golang.org/x/crypto/ssh/handshake.go b/vendor/golang.org/x/crypto/ssh/handshake.go
index 70a7369..e14eb6c 100644
--- a/vendor/golang.org/x/crypto/ssh/handshake.go
+++ b/vendor/golang.org/x/crypto/ssh/handshake.go
@@ -24,6 +24,11 @@ const debugHandshake = false
// quickly.
const chanSize = 16

+// maxPendingPackets sets the maximum number of packets to queue while waiting
+// for KEX to complete. This limits the total pending data to maxPendingPackets
+// * maxPacket bytes, which is ~16.8MB.
+const maxPendingPackets = 64
+
// keyingTransport is a packet based transport that supports key
// changes. It need not be thread-safe. It should pass through
// msgNewKeys in both directions.
@@ -58,11 +63,19 @@ type handshakeTransport struct {
incoming chan []byte
readError error

- mu sync.Mutex
- writeError error
- sentInitPacket []byte
- sentInitMsg *kexInitMsg
- pendingPackets [][]byte // Used when a key exchange is in progress.
+ mu sync.Mutex
+ // Condition for the above mutex. It is used to notify a completed key
+ // exchange or a write failure. Writes can wait for this condition while a
+ // key exchange is in progress.
+ writeCond *sync.Cond
+ writeError error
+ sentInitPacket []byte
+ sentInitMsg *kexInitMsg
+ // Used to queue writes when a key exchange is in progress. The length is
+ // limited by pendingPacketsSize. Once full, writes will block until the key
+ // exchange is completed or an error occurs. If not empty, it is emptied
+ // all at once when the key exchange is completed in kexLoop.
+ pendingPackets [][]byte
writePacketsLeft uint32
writeBytesLeft int64

@@ -114,6 +127,7 @@ func newHandshakeTransport(conn keyingTransport, config *Config, clientVersion,

config: config,
}
+ t.writeCond = sync.NewCond(&t.mu)
t.resetReadThresholds()
t.resetWriteThresholds()

@@ -236,6 +250,7 @@ func (t *handshakeTransport) recordWriteError(err error) {
defer t.mu.Unlock()
if t.writeError == nil && err != nil {
t.writeError = err
+ t.writeCond.Broadcast()
}
}

@@ -339,6 +354,8 @@ write:
}
}
t.pendingPackets = t.pendingPackets[:0]
+ // Unblock writePacket if waiting for KEX.
+ t.writeCond.Broadcast()
t.mu.Unlock()
}

@@ -526,11 +543,20 @@ func (t *handshakeTransport) writePacket(p []byte) error {
}

if t.sentInitMsg != nil {
- // Copy the packet so the writer can reuse the buffer.
- cp := make([]byte, len(p))
- copy(cp, p)
- t.pendingPackets = append(t.pendingPackets, cp)
- return nil
+ if len(t.pendingPackets) < maxPendingPackets {
+ // Copy the packet so the writer can reuse the buffer.
+ cp := make([]byte, len(p))
+ copy(cp, p)
+ t.pendingPackets = append(t.pendingPackets, cp)
+ return nil
+ }
+ for t.sentInitMsg != nil {
+ // Block and wait for KEX to complete or an error.
+ t.writeCond.Wait()
+ if t.writeError != nil {
+ return t.writeError
+ }
+ }
}

if t.writeBytesLeft > 0 {
@@ -547,6 +573,7 @@ func (t *handshakeTransport) writePacket(p []byte) error {

if err := t.pushPacket(p); err != nil {
t.writeError = err
+ t.writeCond.Broadcast()
}

return nil
--
2.45.2
58 changes: 58 additions & 0 deletions SPECS/caddy/CVE-2025-22872.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
From 9ba151b580e96d9fe4f9a400f91e726119546fff Mon Sep 17 00:00:00 2001
From: Roland Shoemaker <[email protected]>
Date: Mon, 24 Feb 2025 11:18:31 -0800
Subject: [PATCH] html: properly handle trailing solidus in unquoted attribute
value in foreign content

The parser properly treats tags like <p a=/> as <p a="/">, but the
tokenizer emits the SelfClosingTagToken token incorrectly. When the
parser is used to parse foreign content, this results in an incorrect
DOM.

Thanks to Sean Ng (https://ensy.zip) for reporting this issue.

Fixes golang/go#73070
Fixes CVE-2025-22872

Change-Id: I65c18df6d6244bf943b61e6c7a87895929e78f4f
Reviewed-on: https://go-review.googlesource.com/c/net/+/661256
Reviewed-by: Neal Patel <[email protected]>
Reviewed-by: Roland Shoemaker <[email protected]>
LUCI-TryBot-Result: Go LUCI <[email protected]>
Auto-Submit: Gopher Robot <[email protected]>
---
vendor/golang.org/x/net/html/token.go | 18 ++++++++++++++++--
1 file changed, 16 insertions(+), 2 deletions(-)

diff --git a/vendor/golang.org/x/net/html/token.go b/vendor/golang.org/x/net/html/token.go
index 3c57880..6598c1f 100644
--- a/vendor/golang.org/x/net/html/token.go
+++ b/vendor/golang.org/x/net/html/token.go
@@ -839,8 +839,22 @@ func (z *Tokenizer) readStartTag() TokenType {
if raw {
z.rawTag = strings.ToLower(string(z.buf[z.data.start:z.data.end]))
}
- // Look for a self-closing token like "<br/>".
- if z.err == nil && z.buf[z.raw.end-2] == '/' {
+ // Look for a self-closing token (e.g. <br/>).
+ //
+ // Originally, we did this by just checking that the last character of the
+ // tag (ignoring the closing bracket) was a solidus (/) character, but this
+ // is not always accurate.
+ //
+ // We need to be careful that we don't misinterpret a non-self-closing tag
+ // as self-closing, as can happen if the tag contains unquoted attribute
+ // values (i.e. <p a=/>).
+ //
+ // To avoid this, we check that the last non-bracket character of the tag
+ // (z.raw.end-2) isn't the same character as the last non-quote character of
+ // the last attribute of the tag (z.pendingAttr[1].end-1), if the tag has
+ // attributes.
+ nAttrs := len(z.attr)
+ if z.err == nil && z.buf[z.raw.end-2] == '/' && (nAttrs == 0 || z.raw.end-2 != z.attr[nAttrs-1][1].end-1) {
return SelfClosingTagToken
}
return StartTagToken
--
2.34.1

Loading
Loading