diff options
Diffstat (limited to 'app-containers/runc/files')
-rw-r--r-- | app-containers/runc/files/CVE-2021-43784.patch | 86 |
1 files changed, 86 insertions, 0 deletions
diff --git a/app-containers/runc/files/CVE-2021-43784.patch b/app-containers/runc/files/CVE-2021-43784.patch new file mode 100644 index 000000000000..ab3886ee9ba7 --- /dev/null +++ b/app-containers/runc/files/CVE-2021-43784.patch @@ -0,0 +1,86 @@ +From b8dbe46687c2a96efa9252b69d3fc1ce33bdc416 Mon Sep 17 00:00:00 2001 +From: Aleksa Sarai <cyphar@cyphar.com> +Date: Thu, 18 Nov 2021 16:12:59 +1100 +Subject: [PATCH] runc init: avoid netlink message length overflows + +When writing netlink messages, it is possible to have a byte array +larger than UINT16_MAX which would result in the length field +overflowing and allowing user-controlled data to be parsed as control +characters (such as creating custom mount points, changing which set of +namespaces to allow, and so on). + +Co-authored-by: Kir Kolyshkin <kolyshkin@gmail.com> +Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com> +Signed-off-by: Aleksa Sarai <cyphar@cyphar.com> +--- + libcontainer/container_linux.go | 20 +++++++++++++++++++- + libcontainer/message_linux.go | 9 +++++++++ + 2 files changed, 28 insertions(+), 1 deletion(-) + +diff --git a/libcontainer/container_linux.go b/libcontainer/container_linux.go +index 6ce1854f68..1484703b0c 100644 +--- a/libcontainer/container_linux.go ++++ b/libcontainer/container_linux.go +@@ -2028,16 +2028,34 @@ func encodeIDMapping(idMap []configs.IDMap) ([]byte, error) { + return data.Bytes(), nil + } + ++// netlinkError is an error wrapper type for use by custom netlink message ++// types. Panics with errors are wrapped in netlinkError so that the recover ++// in bootstrapData can distinguish intentional panics. ++type netlinkError struct{ error } ++ + // bootstrapData encodes the necessary data in netlink binary format + // as a io.Reader. + // Consumer can write the data to a bootstrap program + // such as one that uses nsenter package to bootstrap the container's + // init process correctly, i.e. with correct namespaces, uid/gid + // mapping etc. +-func (c *linuxContainer) bootstrapData(cloneFlags uintptr, nsMaps map[configs.NamespaceType]string) (io.Reader, error) { ++func (c *linuxContainer) bootstrapData(cloneFlags uintptr, nsMaps map[configs.NamespaceType]string) (_ io.Reader, Err error) { + // create the netlink message + r := nl.NewNetlinkRequest(int(InitMsg), 0) + ++ // Our custom messages cannot bubble up an error using returns, instead ++ // they will panic with the specific error type, netlinkError. In that ++ // case, recover from the panic and return that as an error. ++ defer func() { ++ if r := recover(); r != nil { ++ if e, ok := r.(netlinkError); ok { ++ Err = e.error ++ } else { ++ panic(r) ++ } ++ } ++ }() ++ + // write cloneFlags + r.AddData(&Int32msg{ + Type: CloneFlagsAttr, +diff --git a/libcontainer/message_linux.go b/libcontainer/message_linux.go +index 1d4f5033aa..e4107ce39f 100644 +--- a/libcontainer/message_linux.go ++++ b/libcontainer/message_linux.go +@@ -3,6 +3,9 @@ + package libcontainer + + import ( ++ "fmt" ++ "math" ++ + "github.com/vishvananda/netlink/nl" + "golang.org/x/sys/unix" + ) +@@ -54,6 +57,12 @@ type Bytemsg struct { + + func (msg *Bytemsg) Serialize() []byte { + l := msg.Len() ++ if l > math.MaxUint16 { ++ // We cannot return nil nor an error here, so we panic with ++ // a specific type instead, which is handled via recover in ++ // bootstrapData. ++ panic(netlinkError{fmt.Errorf("netlink: cannot serialize bytemsg of length %d (larger than UINT16_MAX)", l)}) ++ } + buf := make([]byte, (l+unix.NLA_ALIGNTO-1) & ^(unix.NLA_ALIGNTO-1)) + native := nl.NativeEndian() + native.PutUint16(buf[0:2], uint16(l)) |