From f0b96c0c72ec661caab3fcd7418a956d40294806 Mon Sep 17 00:00:00 2001 From: h_xuming <2298061238@qq.com> Date: Tue, 18 Jun 2024 21:21:15 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BB=8E22.03-SP3=E5=90=88=E5=B9=B6=E5=88=B022?= =?UTF-8?q?.03-SP4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 0001-Fix-CVE-2023-25153.patch | 36 +++ 0002-Fix-CVE-2022-23471.patch | 59 ++++ ...ack-of-RAPL-accessible-to-a-containe.patch | 41 +++ 0004-fix-CVE-2023-25173.patch | 267 ++++++++++++++++++ 0005-fix-CVE-2023-39325.patch | 148 ++++++++++ 0006-fix-CVE-2022-41723.patch | 159 +++++++++++ 0007-fix-CVE-2024-24786.patch | 59 ++++ k3s-containerd.spec | 54 +++- 8 files changed, 821 insertions(+), 2 deletions(-) create mode 100644 0001-Fix-CVE-2023-25153.patch create mode 100644 0002-Fix-CVE-2022-23471.patch create mode 100644 0003-fix-PLATYPUS-attack-of-RAPL-accessible-to-a-containe.patch create mode 100644 0004-fix-CVE-2023-25173.patch create mode 100644 0005-fix-CVE-2023-39325.patch create mode 100644 0006-fix-CVE-2022-41723.patch create mode 100644 0007-fix-CVE-2024-24786.patch diff --git a/0001-Fix-CVE-2023-25153.patch b/0001-Fix-CVE-2023-25153.patch new file mode 100644 index 0000000..aa6abe0 --- /dev/null +++ b/0001-Fix-CVE-2023-25153.patch @@ -0,0 +1,36 @@ +From e1ec32e24f11bb3f003ef876e404777c1041349b Mon Sep 17 00:00:00 2001 +From: bwzhang +Date: Wed, 13 Mar 2024 15:03:38 +0800 +Subject: [PATCH] Fix CVE-2023-25153 + +--- + images/archive/importer.go | 12 +++++++----- + 1 file changed, 7 insertions(+), 5 deletions(-) + +diff --git a/images/archive/importer.go b/images/archive/importer.go +index c531049..8ba3206 100644 +--- a/images/archive/importer.go ++++ b/images/archive/importer.go +@@ -232,12 +232,14 @@ func ImportIndex(ctx context.Context, store content.Store, reader io.Reader, opt + return writeManifest(ctx, store, idx, ocispec.MediaTypeImageIndex) + } + ++const ( ++ kib = 1024 ++ mib = 1024 * kib ++ jsonLimit = 20 * mib ++) ++ + func onUntarJSON(r io.Reader, j interface{}) error { +- b, err := io.ReadAll(r) +- if err != nil { +- return err +- } +- return json.Unmarshal(b, j) ++ return json.NewDecoder(io.LimitReader(r, jsonLimit)).Decode(j) + } + + func onUntarBlob(ctx context.Context, r io.Reader, store content.Ingester, size int64, ref string) (digest.Digest, error) { +-- +2.20.1 + diff --git a/0002-Fix-CVE-2022-23471.patch b/0002-Fix-CVE-2022-23471.patch new file mode 100644 index 0000000..016b034 --- /dev/null +++ b/0002-Fix-CVE-2022-23471.patch @@ -0,0 +1,59 @@ +From 0550bb17949c1793e0da20270d3793d0e7583b1e Mon Sep 17 00:00:00 2001 +From: bwzhang +Date: Fri, 15 Mar 2024 09:33:45 +0800 +Subject: [PATCH] Fix CVE-2022-23471 + +--- + pkg/cri/streaming/remotecommand/httpstream.go | 15 ++++++++++++--- + 1 file changed, 12 insertions(+), 3 deletions(-) + +diff --git a/pkg/cri/streaming/remotecommand/httpstream.go b/pkg/cri/streaming/remotecommand/httpstream.go +index 0417a1a..9177fa7 100644 +--- a/pkg/cri/streaming/remotecommand/httpstream.go ++++ b/pkg/cri/streaming/remotecommand/httpstream.go +@@ -33,6 +33,7 @@ limitations under the License. + package remotecommand + + import ( ++ gocontext "context" + "encoding/json" + "errors" + "fmt" +@@ -132,7 +133,7 @@ func createStreams(req *http.Request, w http.ResponseWriter, opts *Options, supp + + if ctx.resizeStream != nil { + ctx.resizeChan = make(chan remotecommand.TerminalSize) +- go handleResizeEvents(ctx.resizeStream, ctx.resizeChan) ++ go handleResizeEvents(req.Context(), ctx.resizeStream, ctx.resizeChan) + } + + return ctx, true +@@ -425,7 +426,7 @@ WaitForStreams: + // supportsTerminalResizing returns false because v1ProtocolHandler doesn't support it. + func (*v1ProtocolHandler) supportsTerminalResizing() bool { return false } + +-func handleResizeEvents(stream io.Reader, channel chan<- remotecommand.TerminalSize) { ++func handleResizeEvents(ctx gocontext.Context, stream io.Reader, channel chan<- remotecommand.TerminalSize) { + defer runtime.HandleCrash() + defer close(channel) + +@@ -435,7 +436,15 @@ func handleResizeEvents(stream io.Reader, channel chan<- remotecommand.TerminalS + if err := decoder.Decode(&size); err != nil { + break + } +- channel <- size ++ ++ select { ++ case channel <- size: ++ case <-ctx.Done(): ++ // To avoid leaking this routine, exit if the http request finishes. This path ++ // would generally be hit if starting the process fails and nothing is started to ++ // ingest these resize events. ++ return ++ } + } + } + +-- +2.20.1 + diff --git a/0003-fix-PLATYPUS-attack-of-RAPL-accessible-to-a-containe.patch b/0003-fix-PLATYPUS-attack-of-RAPL-accessible-to-a-containe.patch new file mode 100644 index 0000000..f34921c --- /dev/null +++ b/0003-fix-PLATYPUS-attack-of-RAPL-accessible-to-a-containe.patch @@ -0,0 +1,41 @@ +From e3b8749e93d2412385498c9ed6cf6550b2992aaf Mon Sep 17 00:00:00 2001 +From: bwzhang +Date: Mon, 18 Mar 2024 15:06:38 +0800 +Subject: [PATCH] fix PLATYPUS attack of RAPL accessible to a container + Security Advisories: + https://github.com/containerd/containerd/security/advisories/GHSA-7ww5-4wqc-m92c + upstream: + https://github.com/containerd/containerd/commit/9e4d53df751605b2c3fa12ed062f8d7a76c0b3f3 + +--- + contrib/apparmor/template.go | 1 + + oci/spec.go | 1 + + 2 files changed, 2 insertions(+) + +diff --git a/contrib/apparmor/template.go b/contrib/apparmor/template.go +index ba613c3..5c4f785 100644 +--- a/contrib/apparmor/template.go ++++ b/contrib/apparmor/template.go +@@ -81,6 +81,7 @@ profile {{.Name}} flags=(attach_disconnected,mediate_deleted) { + deny /sys/fs/c[^g]*/** wklx, + deny /sys/fs/cg[^r]*/** wklx, + deny /sys/firmware/** rwklx, ++ deny /sys/devices/virtual/powercap/** rwklx, + deny /sys/kernel/security/** rwklx, + + {{if ge .Version 208095}} +diff --git a/oci/spec.go b/oci/spec.go +index a1c98dd..62d212a 100644 +--- a/oci/spec.go ++++ b/oci/spec.go +@@ -171,6 +171,7 @@ func populateDefaultUnixSpec(ctx context.Context, s *Spec, id string) error { + "/proc/timer_stats", + "/proc/sched_debug", + "/sys/firmware", ++ "/sys/devices/virtual/powercap", + "/proc/scsi", + }, + ReadonlyPaths: []string{ +-- +2.20.1 + diff --git a/0004-fix-CVE-2023-25173.patch b/0004-fix-CVE-2023-25173.patch new file mode 100644 index 0000000..4f03058 --- /dev/null +++ b/0004-fix-CVE-2023-25173.patch @@ -0,0 +1,267 @@ +From 1b69407142a4a42d6d81cd0a3ec7db15fb270031 Mon Sep 17 00:00:00 2001 +From: bwzhang +Date: Tue, 19 Mar 2024 10:07:46 +0800 +Subject: [PATCH] fix CVE-2023-25173 + +--- + oci/spec_opts.go | 139 +++++++++++++++++------ + pkg/cri/server/container_create_linux.go | 3 +- + 2 files changed, 105 insertions(+), 37 deletions(-) + +diff --git a/oci/spec_opts.go b/oci/spec_opts.go +index 36eae16..c9e1832 100644 +--- a/oci/spec_opts.go ++++ b/oci/spec_opts.go +@@ -113,6 +113,17 @@ func setCapabilities(s *Spec) { + } + } + ++// ensureAdditionalGids ensures that the primary GID is also included in the additional GID list. ++func ensureAdditionalGids(s *Spec) { ++ setProcess(s) ++ for _, f := range s.Process.User.AdditionalGids { ++ if f == s.Process.User.GID { ++ return ++ } ++ } ++ s.Process.User.AdditionalGids = append([]uint32{s.Process.User.GID}, s.Process.User.AdditionalGids...) ++} ++ + // WithDefaultSpec returns a SpecOpts that will populate the spec with default + // values. + // +@@ -521,7 +532,9 @@ func WithNamespacedCgroup() SpecOpts { + // user, uid, user:group, uid:gid, uid:group, user:gid + func WithUser(userstr string) SpecOpts { + return func(ctx context.Context, client Client, c *containers.Container, s *Spec) error { ++ defer ensureAdditionalGids(s) + setProcess(s) ++ s.Process.User.AdditionalGids = nil + + // For LCOW it's a bit harder to confirm that the user actually exists on the host as a rootfs isn't + // mounted on the host and shared into the guest, but rather the rootfs is constructed entirely in the +@@ -614,7 +627,9 @@ func WithUser(userstr string) SpecOpts { + // WithUIDGID allows the UID and GID for the Process to be set + func WithUIDGID(uid, gid uint32) SpecOpts { + return func(_ context.Context, _ Client, _ *containers.Container, s *Spec) error { ++ defer ensureAdditionalGids(s) + setProcess(s) ++ s.Process.User.AdditionalGids = nil + s.Process.User.UID = uid + s.Process.User.GID = gid + return nil +@@ -627,12 +642,11 @@ func WithUIDGID(uid, gid uint32) SpecOpts { + // additionally sets the gid to 0, and does not return an error. + func WithUserID(uid uint32) SpecOpts { + return func(ctx context.Context, client Client, c *containers.Container, s *Spec) (err error) { ++ defer ensureAdditionalGids(s) + setProcess(s) +- if c.Snapshotter == "" && c.SnapshotKey == "" { +- if !isRootfsAbs(s.Root.Path) { +- return errors.New("rootfs absolute path is required") +- } +- user, err := UserFromPath(s.Root.Path, func(u user.User) bool { ++ s.Process.User.AdditionalGids = nil ++ setUser := func(root string) error { ++ user, err := UserFromPath(root, func(u user.User) bool { + return u.Uid == int(uid) + }) + if err != nil { +@@ -644,6 +658,12 @@ func WithUserID(uid uint32) SpecOpts { + } + s.Process.User.UID, s.Process.User.GID = uint32(user.Uid), uint32(user.Gid) + return nil ++ } ++ if c.Snapshotter == "" && c.SnapshotKey == "" { ++ if !isRootfsAbs(s.Root.Path) { ++ return errors.New("rootfs absolute path is required") ++ } ++ return setUser(s.Root.Path) + + } + if c.Snapshotter == "" { +@@ -659,20 +679,7 @@ func WithUserID(uid uint32) SpecOpts { + } + + mounts = tryReadonlyMounts(mounts) +- return mount.WithTempMount(ctx, mounts, func(root string) error { +- user, err := UserFromPath(root, func(u user.User) bool { +- return u.Uid == int(uid) +- }) +- if err != nil { +- if os.IsNotExist(err) || err == ErrNoUsersFound { +- s.Process.User.UID, s.Process.User.GID = uid, 0 +- return nil +- } +- return err +- } +- s.Process.User.UID, s.Process.User.GID = uint32(user.Uid), uint32(user.Gid) +- return nil +- }) ++ return mount.WithTempMount(ctx, mounts, setUser) + } + } + +@@ -684,13 +691,12 @@ func WithUserID(uid uint32) SpecOpts { + // the container. + func WithUsername(username string) SpecOpts { + return func(ctx context.Context, client Client, c *containers.Container, s *Spec) (err error) { ++ defer ensureAdditionalGids(s) + setProcess(s) ++ s.Process.User.AdditionalGids = nil + if s.Linux != nil { +- if c.Snapshotter == "" && c.SnapshotKey == "" { +- if !isRootfsAbs(s.Root.Path) { +- return errors.New("rootfs absolute path is required") +- } +- user, err := UserFromPath(s.Root.Path, func(u user.User) bool { ++ setUser := func(root string) error { ++ user, err := UserFromPath(root, func(u user.User) bool { + return u.Name == username + }) + if err != nil { +@@ -699,6 +705,12 @@ func WithUsername(username string) SpecOpts { + s.Process.User.UID, s.Process.User.GID = uint32(user.Uid), uint32(user.Gid) + return nil + } ++ if c.Snapshotter == "" && c.SnapshotKey == "" { ++ if !isRootfsAbs(s.Root.Path) { ++ return errors.New("rootfs absolute path is required") ++ } ++ return setUser(s.Root.Path) ++ } + if c.Snapshotter == "" { + return errors.New("no snapshotter set for container") + } +@@ -712,16 +724,7 @@ func WithUsername(username string) SpecOpts { + } + + mounts = tryReadonlyMounts(mounts) +- return mount.WithTempMount(ctx, mounts, func(root string) error { +- user, err := UserFromPath(root, func(u user.User) bool { +- return u.Name == username +- }) +- if err != nil { +- return err +- } +- s.Process.User.UID, s.Process.User.GID = uint32(user.Uid), uint32(user.Gid) +- return nil +- }) ++ return mount.WithTempMount(ctx, mounts, setUser) + } else if s.Windows != nil { + s.Process.User.Username = username + } else { +@@ -732,7 +735,7 @@ func WithUsername(username string) SpecOpts { + } + + // WithAdditionalGIDs sets the OCI spec's additionalGids array to any additional groups listed +-// for a particular user in the /etc/groups file of the image's root filesystem ++// for a particular user in the /etc/group file of the image's root filesystem + // The passed in user can be either a uid or a username. + func WithAdditionalGIDs(userstr string) SpecOpts { + return func(ctx context.Context, client Client, c *containers.Container, s *Spec) (err error) { +@@ -741,7 +744,9 @@ func WithAdditionalGIDs(userstr string) SpecOpts { + return nil + } + setProcess(s) ++ s.Process.User.AdditionalGids = nil + setAdditionalGids := func(root string) error { ++ defer ensureAdditionalGids(s) + var username string + uid, err := strconv.Atoi(userstr) + if err == nil { +@@ -802,6 +807,68 @@ func WithAdditionalGIDs(userstr string) SpecOpts { + } + } + ++// WithAppendAdditionalGroups append additional groups within the container. ++// The passed in groups can be either a gid or a groupname. ++func WithAppendAdditionalGroups(groups ...string) SpecOpts { ++ return func(ctx context.Context, client Client, c *containers.Container, s *Spec) (err error) { ++ // For LCOW or on Darwin additional GID's are not supported ++ if s.Windows != nil || runtime.GOOS == "darwin" { ++ return nil ++ } ++ setProcess(s) ++ setAdditionalGids := func(root string) error { ++ defer ensureAdditionalGids(s) ++ gpath, err := fs.RootPath(root, "/etc/group") ++ if err != nil { ++ return err ++ } ++ ugroups, err := user.ParseGroupFile(gpath) ++ if err != nil { ++ return err ++ } ++ groupMap := make(map[string]user.Group) ++ for _, group := range ugroups { ++ groupMap[group.Name] = group ++ } ++ var gids []uint32 ++ for _, group := range groups { ++ gid, err := strconv.ParseUint(group, 10, 32) ++ if err == nil { ++ gids = append(gids, uint32(gid)) ++ } else { ++ g, ok := groupMap[group] ++ if !ok { ++ return fmt.Errorf("unable to find group %s", group) ++ } ++ gids = append(gids, uint32(g.Gid)) ++ } ++ } ++ s.Process.User.AdditionalGids = append(s.Process.User.AdditionalGids, gids...) ++ return nil ++ } ++ if c.Snapshotter == "" && c.SnapshotKey == "" { ++ if !filepath.IsAbs(s.Root.Path) { ++ return errors.New("rootfs absolute path is required") ++ } ++ return setAdditionalGids(s.Root.Path) ++ } ++ if c.Snapshotter == "" { ++ return errors.New("no snapshotter set for container") ++ } ++ if c.SnapshotKey == "" { ++ return errors.New("rootfs snapshot not created for container") ++ } ++ snapshotter := client.SnapshotService(c.Snapshotter) ++ mounts, err := snapshotter.Mounts(ctx, c.SnapshotKey) ++ if err != nil { ++ return err ++ } ++ ++ mounts = tryReadonlyMounts(mounts) ++ return mount.WithTempMount(ctx, mounts, setAdditionalGids) ++ } ++} ++ + // WithCapabilities sets Linux capabilities on the process + func WithCapabilities(caps []string) SpecOpts { + return func(_ context.Context, _ Client, _ *containers.Container, s *Spec) error { +@@ -906,7 +973,7 @@ func UserFromPath(root string, filter func(user.User) bool) (user.User, error) { + // ErrNoGroupsFound can be returned from GIDFromPath + var ErrNoGroupsFound = errors.New("no groups found") + +-// GIDFromPath inspects the GID using /etc/passwd in the specified rootfs. ++// GIDFromPath inspects the GID using /etc/group in the specified rootfs. + // filter can be nil. + func GIDFromPath(root string, filter func(user.Group) bool) (gid uint32, err error) { + gpath, err := fs.RootPath(root, "/etc/group") +diff --git a/pkg/cri/server/container_create_linux.go b/pkg/cri/server/container_create_linux.go +index 8fb41e2..c428fe8 100644 +--- a/pkg/cri/server/container_create_linux.go ++++ b/pkg/cri/server/container_create_linux.go +@@ -347,7 +347,8 @@ func (c *criService) containerSpecOpts(config *runtime.ContainerConfig, imageCon + // Because it is still useful to get additional gids for uid 0. + userstr = strconv.FormatInt(securityContext.GetRunAsUser().GetValue(), 10) + } +- specOpts = append(specOpts, customopts.WithAdditionalGIDs(userstr)) ++ specOpts = append(specOpts, customopts.WithAdditionalGIDs(userstr), ++ customopts.WithSupplementalGroups(securityContext.GetSupplementalGroups())) + + asp := securityContext.GetApparmor() + if asp == nil { +-- +2.20.1 + diff --git a/0005-fix-CVE-2023-39325.patch b/0005-fix-CVE-2023-39325.patch new file mode 100644 index 0000000..399fb12 --- /dev/null +++ b/0005-fix-CVE-2023-39325.patch @@ -0,0 +1,148 @@ +From e9a63ee00a048c15b719c5cab0241a5d58901464 Mon Sep 17 00:00:00 2001 +From: bwzhang +Date: Thu, 21 Mar 2024 10:57:12 +0800 +Subject: [PATCH] fix CVE-2023-39325 Pull in a security fix from x/net/http2: + http2: limit maximum handler goroutines to MaxConcurrentStreamso + +For #63417 +Fixes #63426 +Fixes CVE-2023-39325 + +Change-Id: I6e32397323cd9b4114c990fcc9d19557a7f5f619 +Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/2047401 +Reviewed-by: Tatiana Bradley +TryBot-Result: Security TryBots +Run-TryBot: Damien Neil +Reviewed-by: Ian Cottrell +Reviewed-on: https://go-review.googlesource.com/c/go/+/534255 +Reviewed-by: Dmitri Shuralyov +Reviewed-by: Damien Neil +TryBot-Bypass: Dmitri Shuralyov +Reviewed-by: Michael Pratt +Auto-Submit: Dmitri Shuralyov +--- + vendor/golang.org/x/net/http2/server.go | 63 ++++++++++++++++++++++++- + 1 file changed, 61 insertions(+), 2 deletions(-) + +diff --git a/vendor/golang.org/x/net/http2/server.go b/vendor/golang.org/x/net/http2/server.go +index e644d9b..432e2f1 100644 +--- a/vendor/golang.org/x/net/http2/server.go ++++ b/vendor/golang.org/x/net/http2/server.go +@@ -520,9 +520,11 @@ type serverConn struct { + advMaxStreams uint32 // our SETTINGS_MAX_CONCURRENT_STREAMS advertised the client + curClientStreams uint32 // number of open streams initiated by the client + curPushedStreams uint32 // number of open streams initiated by server push ++ curHandlers uint32 // number of running handler goroutines + maxClientStreamID uint32 // max ever seen from client (odd), or 0 if there have been no client requests + maxPushPromiseID uint32 // ID of the last push promise (even), or 0 if there have been no pushes + streams map[uint32]*stream ++ unstartedHandlers []unstartedHandler + initialStreamSendWindowSize int32 + maxFrameSize int32 + headerTableSize uint32 +@@ -909,6 +911,8 @@ func (sc *serverConn) serve() { + return + case gracefulShutdownMsg: + sc.startGracefulShutdownInternal() ++ case handlerDoneMsg: ++ sc.handlerDone() + default: + panic("unknown timer") + } +@@ -954,6 +958,7 @@ var ( + idleTimerMsg = new(serverMessage) + shutdownTimerMsg = new(serverMessage) + gracefulShutdownMsg = new(serverMessage) ++ handlerDoneMsg = new(serverMessage) + ) + + func (sc *serverConn) onSettingsTimer() { sc.sendServeMsg(settingsTimerMsg) } +@@ -1911,8 +1916,7 @@ func (sc *serverConn) processHeaders(f *MetaHeadersFrame) error { + sc.conn.SetReadDeadline(time.Time{}) + } + +- go sc.runHandler(rw, req, handler) +- return nil ++ return sc.scheduleHandler(id, rw, req, handler) + } + + func (st *stream) processTrailerHeaders(f *MetaHeadersFrame) error { +@@ -1945,6 +1949,59 @@ func (st *stream) processTrailerHeaders(f *MetaHeadersFrame) error { + return nil + } + ++type unstartedHandler struct { ++ streamID uint32 ++ rw *responseWriter ++ req *http.Request ++ handler func(http.ResponseWriter, *http.Request) ++} ++ ++// scheduleHandler starts a handler goroutine, ++// or schedules one to start as soon as an existing handler finishes. ++func (sc *serverConn) scheduleHandler(streamID uint32, rw *responseWriter, req *http.Request, handler func(http.ResponseWriter, *http.Request)) error { ++ sc.serveG.check() ++ maxHandlers := sc.advMaxStreams ++ if sc.curHandlers < maxHandlers { ++ sc.curHandlers++ ++ go sc.runHandler(rw, req, handler) ++ return nil ++ } ++ if len(sc.unstartedHandlers) > int(4*sc.advMaxStreams) { ++ return ConnectionError(ErrCodeEnhanceYourCalm) ++ } ++ sc.unstartedHandlers = append(sc.unstartedHandlers, unstartedHandler{ ++ streamID: streamID, ++ rw: rw, ++ req: req, ++ handler: handler, ++ }) ++ return nil ++} ++ ++func (sc *serverConn) handlerDone() { ++ sc.serveG.check() ++ sc.curHandlers-- ++ i := 0 ++ maxHandlers := sc.advMaxStreams ++ for ; i < len(sc.unstartedHandlers); i++ { ++ u := sc.unstartedHandlers[i] ++ if sc.streams[u.streamID] == nil { ++ // This stream was reset before its goroutine had a chance to start. ++ continue ++ } ++ if sc.curHandlers >= maxHandlers { ++ break ++ } ++ sc.curHandlers++ ++ go sc.runHandler(u.rw, u.req, u.handler) ++ sc.unstartedHandlers[i] = unstartedHandler{} // don't retain references ++ } ++ sc.unstartedHandlers = sc.unstartedHandlers[i:] ++ if len(sc.unstartedHandlers) == 0 { ++ sc.unstartedHandlers = nil ++ } ++} ++ + func (sc *serverConn) checkPriority(streamID uint32, p PriorityParam) error { + if streamID == p.StreamDep { + // Section 5.3.1: "A stream cannot depend on itself. An endpoint MUST treat +@@ -2161,6 +2218,7 @@ func (sc *serverConn) newWriterAndRequestNoBody(st *stream, rp requestParam) (*r + + // Run on its own goroutine. + func (sc *serverConn) runHandler(rw *responseWriter, req *http.Request, handler func(http.ResponseWriter, *http.Request)) { ++ defer sc.sendServeMsg(handlerDoneMsg) + didPanic := true + defer func() { + rw.rws.stream.cancelCtx() +@@ -2923,6 +2981,7 @@ func (sc *serverConn) startPush(msg *startPushRequest) { + panic(fmt.Sprintf("newWriterAndRequestNoBody(%+v): %v", msg.url, err)) + } + ++ sc.curHandlers++ + go sc.runHandler(rw, req, sc.handler.ServeHTTP) + return promisedID, nil + } +-- +2.20.1 + diff --git a/0006-fix-CVE-2022-41723.patch b/0006-fix-CVE-2022-41723.patch new file mode 100644 index 0000000..5b495ad --- /dev/null +++ b/0006-fix-CVE-2022-41723.patch @@ -0,0 +1,159 @@ +From 6ea59034fb15b3649c70078065e15fd5bfff601d Mon Sep 17 00:00:00 2001 +From: bwzhang +Date: Fri, 22 Mar 2024 09:24:48 +0800 +Subject: [PATCH] fix CVE-2022-41723 + +http2/hpack: avoid quadratic complexity in hpack decoding + +When parsing a field literal containing two Huffman-encoded strings, +don't decode the first string until verifying all data is present. +Avoids forced quadratic complexity when repeatedly parsing a partial +field, repeating the Huffman decoding of the string on each iteration. + +Thanks to Philippe Antoine (Catena cyber) for reporting this issue. + +Fixes golang/go#57855 +Fixes CVE-2022-41723 + +Change-Id: I58a743df450a4a4923dddd5cf6bb0592b0a7bdf3 +Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/1688184 +TryBot-Result: Security TryBots +Reviewed-by: Julie Qiu +Run-TryBot: Damien Neil +Reviewed-by: Roland Shoemaker +Reviewed-on: https://go-review.googlesource.com/c/net/+/468135 +Run-TryBot: Michael Pratt +Reviewed-by: Roland Shoemaker +Reviewed-by: Than McIntosh +Auto-Submit: Michael Pratt +TryBot-Result: Gopher Robot +--- + vendor/golang.org/x/net/http2/hpack/hpack.go | 79 ++++++++++++-------- + 1 file changed, 49 insertions(+), 30 deletions(-) + +diff --git a/vendor/golang.org/x/net/http2/hpack/hpack.go b/vendor/golang.org/x/net/http2/hpack/hpack.go +index 85f18a2..279cccc 100644 +--- a/vendor/golang.org/x/net/http2/hpack/hpack.go ++++ b/vendor/golang.org/x/net/http2/hpack/hpack.go +@@ -359,6 +359,7 @@ func (d *Decoder) parseFieldLiteral(n uint8, it indexType) error { + + var hf HeaderField + wantStr := d.emitEnabled || it.indexed() ++ var undecodedName undecodedString + if nameIdx > 0 { + ihf, ok := d.at(nameIdx) + if !ok { +@@ -366,15 +367,27 @@ func (d *Decoder) parseFieldLiteral(n uint8, it indexType) error { + } + hf.Name = ihf.Name + } else { +- hf.Name, buf, err = d.readString(buf, wantStr) ++ undecodedName, buf, err = d.readString(buf) + if err != nil { + return err + } + } +- hf.Value, buf, err = d.readString(buf, wantStr) ++ undecodedValue, buf, err := d.readString(buf) + if err != nil { + return err + } ++ if wantStr { ++ if nameIdx <= 0 { ++ hf.Name, err = d.decodeString(undecodedName) ++ if err != nil { ++ return err ++ } ++ } ++ hf.Value, err = d.decodeString(undecodedValue) ++ if err != nil { ++ return err ++ } ++ } + d.buf = buf + if it.indexed() { + d.dynTab.add(hf) +@@ -459,46 +472,52 @@ func readVarInt(n byte, p []byte) (i uint64, remain []byte, err error) { + return 0, origP, errNeedMore + } + +-// readString decodes an hpack string from p. ++// readString reads an hpack string from p. + // +-// wantStr is whether s will be used. If false, decompression and +-// []byte->string garbage are skipped if s will be ignored +-// anyway. This does mean that huffman decoding errors for non-indexed +-// strings past the MAX_HEADER_LIST_SIZE are ignored, but the server +-// is returning an error anyway, and because they're not indexed, the error +-// won't affect the decoding state. +-func (d *Decoder) readString(p []byte, wantStr bool) (s string, remain []byte, err error) { ++// It returns a reference to the encoded string data to permit deferring decode costs ++// until after the caller verifies all data is present. ++func (d *Decoder) readString(p []byte) (u undecodedString, remain []byte, err error) { + if len(p) == 0 { +- return "", p, errNeedMore ++ return u, p, errNeedMore + } + isHuff := p[0]&128 != 0 + strLen, p, err := readVarInt(7, p) + if err != nil { +- return "", p, err ++ return u, p, err + } + if d.maxStrLen != 0 && strLen > uint64(d.maxStrLen) { +- return "", nil, ErrStringLength ++ // Returning an error here means Huffman decoding errors ++ // for non-indexed strings past the maximum string length ++ // are ignored, but the server is returning an error anyway ++ // and because the string is not indexed the error will not ++ // affect the decoding state. ++ return u, nil, ErrStringLength + } + if uint64(len(p)) < strLen { +- return "", p, errNeedMore +- } +- if !isHuff { +- if wantStr { +- s = string(p[:strLen]) +- } +- return s, p[strLen:], nil ++ return u, p, errNeedMore + } ++ u.isHuff = isHuff ++ u.b = p[:strLen] ++ return u, p[strLen:], nil ++} + +- if wantStr { +- buf := bufPool.Get().(*bytes.Buffer) +- buf.Reset() // don't trust others +- defer bufPool.Put(buf) +- if err := huffmanDecode(buf, d.maxStrLen, p[:strLen]); err != nil { +- buf.Reset() +- return "", nil, err +- } ++type undecodedString struct { ++ isHuff bool ++ b []byte ++} ++ ++func (d *Decoder) decodeString(u undecodedString) (string, error) { ++ if !u.isHuff { ++ return string(u.b), nil ++ } ++ buf := bufPool.Get().(*bytes.Buffer) ++ buf.Reset() // don't trust others ++ var s string ++ err := huffmanDecode(buf, d.maxStrLen, u.b) ++ if err == nil { + s = buf.String() +- buf.Reset() // be nice to GC + } +- return s, p[strLen:], nil ++ buf.Reset() // be nice to GC ++ bufPool.Put(buf) ++ return s, err + } +-- +2.20.1 + diff --git a/0007-fix-CVE-2024-24786.patch b/0007-fix-CVE-2024-24786.patch new file mode 100644 index 0000000..dd79b26 --- /dev/null +++ b/0007-fix-CVE-2024-24786.patch @@ -0,0 +1,59 @@ +From 171172b7a8a24104415f1d461da7a839dd9933a3 Mon Sep 17 00:00:00 2001 +From: bwzhang +Date: Mon, 25 Mar 2024 10:47:11 +0800 +Subject: [PATCH] fix CVE-2024-24786 + +encoding/protojson, internal/encoding/json: handle missing object values + +In internal/encoding/json, report an error when encountering a } +when we are expecting an object field value. For example, the input + now correctly results in an error at the closing } token. + +In encoding/protojson, check for an unexpected EOF token in +skipJSONValue. This is redundant with the check in internal/encoding/json, +but adds a bit more defense against any other similar bugs that +might exist. + +Fixes CVE-2024-24786 + +Change-Id: I03d52512acb5091c8549e31ca74541d57e56c99d +Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/569356 +TryBot-Bypass: Damien Neil +Reviewed-by: Roland Shoemaker +Commit-Queue: Damien Neil +--- + .../protobuf/encoding/protojson/well_known_types.go | 4 ++++ + .../protobuf/internal/encoding/json/decode.go | 2 +- + 2 files changed, 5 insertions(+), 1 deletion(-) + +diff --git a/vendor/google.golang.org/protobuf/encoding/protojson/well_known_types.go b/vendor/google.golang.org/protobuf/encoding/protojson/well_known_types.go +index 72924a9..d3825ba 100644 +--- a/vendor/google.golang.org/protobuf/encoding/protojson/well_known_types.go ++++ b/vendor/google.golang.org/protobuf/encoding/protojson/well_known_types.go +@@ -328,6 +328,10 @@ func (d decoder) skipJSONValue() error { + if err := d.skipJSONValue(); err != nil { + return err + } ++ case json.EOF: ++ // This can only happen if there's a bug in Decoder.Read. ++ // Avoid an infinite loop if this does happen. ++ return errors.New("unexpected EOF") + } + } + +diff --git a/vendor/google.golang.org/protobuf/internal/encoding/json/decode.go b/vendor/google.golang.org/protobuf/internal/encoding/json/decode.go +index b13fd29..b2be4e8 100644 +--- a/vendor/google.golang.org/protobuf/internal/encoding/json/decode.go ++++ b/vendor/google.golang.org/protobuf/internal/encoding/json/decode.go +@@ -121,7 +121,7 @@ func (d *Decoder) Read() (Token, error) { + + case ObjectClose: + if len(d.openStack) == 0 || +- d.lastToken.kind == comma || ++ d.lastToken.kind&(Name|comma) != 0 || + d.openStack[len(d.openStack)-1] != ObjectOpen { + return Token{}, d.newSyntaxError(tok.pos, unexpectedFmt, tok.RawString()) + } +-- +2.20.1 + diff --git a/k3s-containerd.spec b/k3s-containerd.spec index 9c9f7a8..0e603da 100644 --- a/k3s-containerd.spec +++ b/k3s-containerd.spec @@ -3,12 +3,20 @@ %global version_suffix k3s1 Version: 1.6.6 Name: k3s-containerd -Release: 4 +Release: 11 Summary: An industry-standard container runtime License: Apache-2.0 URL: https://github.com/k3s-io/containerd Source0: https://github.com/k3s-io/containerd/archive/refs/tags/v%{version}-%{version_suffix}.tar.gz +Patch0001: 0001-Fix-CVE-2023-25153.patch +Patch0002: 0002-Fix-CVE-2022-23471.patch +Patch0003: 0003-fix-PLATYPUS-attack-of-RAPL-accessible-to-a-containe.patch +Patch0004: 0004-fix-CVE-2023-25173.patch +Patch0005: 0005-fix-CVE-2023-39325.patch +Patch0006: 0006-fix-CVE-2022-41723.patch +Patch0007: 0007-fix-CVE-2024-24786.patch + BuildRequires: golang glibc-static make btrfs-progs-devel %description @@ -19,7 +27,7 @@ system: image transfer and storage, container execution and supervision, low-level storage and network attachments, etc. %prep -%autosetup -n containerd-%{version}-%{version_suffix} +%autosetup -p1 -n containerd-%{version}-%{version_suffix} %build mkdir -p k3s-containerd/bin @@ -68,6 +76,48 @@ cp -rf %{_builddir}/containerd-%{version}-%{version_suffix}/. %{buildroot}%{_lib %changelog +* Mon Mar 25 2024 zhangbowei - 1.6.6-k3s1-11 +- Type:bugfix +- CVE:NA +- SUG:NA +- DESC: fix CVE-2024-24786 + +* Fri Mar 22 2024 zhangbowei - 1.6.6-k3s1-10 +- Type:bugfix +- CVE:NA +- SUG:NA +- DESC: fix CVE-2022-41723 + +* Thu Mar 21 2024 zhangbowei - 1.6.6-k3s1-9 +- Type:bugfix +- CVE:NA +- SUG:NA +- DESC: fix CVE-2023-39325 + +* Tue Mar 19 2024 zhangbowei - 1.6.6-k3s1-8 +- Type:bugfix +- CVE:NA +- SUG:NA +- DESC: fix CVE-2023-2517 + +* Mon Mar 18 2024 zhangbowei - 1.6.6-k3s1-7 +- Type:bugfix +- CVE:NA +- SUG:NA +- DESC:fix PLATYPUS attack of RAPL accessible to a container + +* Fri Mar 15 2024 zhangbowei - 1.6.6-k3s1-6 +- Type:bugfix +- CVE:NA +- SUG:NA +- DESC: fix CVE-2022-23471 + +* Wed Mar 13 2024 zhangbowei - 1.6.6-k3s1-5 +- Type:bugfix +- CVE:NA +- SUG:NA +- DESC: fix CVE-2023-25153 + * Fri Mar 03 2023 wangkai - 1.6.6-k3s1-4 - Add PIE,BIND_NOW,RELRO secure compilation options -- Gitee