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>
This commit is contained in:
Aleksa Sarai
2021-11-18 16:12:59 +11:00
parent 0c0ec3f53f
commit d72d057ba7
2 changed files with 28 additions and 1 deletions
+9
View File
@@ -1,6 +1,9 @@
package libcontainer
import (
"fmt"
"math"
"github.com/vishvananda/netlink/nl"
"golang.org/x/sys/unix"
)
@@ -53,6 +56,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))