summaryrefslogtreecommitdiff
path: root/app-containers/runc/files/CVE-2021-43784.patch
diff options
context:
space:
mode:
Diffstat (limited to 'app-containers/runc/files/CVE-2021-43784.patch')
-rw-r--r--app-containers/runc/files/CVE-2021-43784.patch86
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))