
runc rc95 contains a fix for CVE-2021-30465. runc rc94 provides fixes and improvements. One notable change is cgroup manager's Set now accept Resources rather than Cgroup (see https://github.com/opencontainers/runc/pull/2906). Modify the code accordingly. Also update runc dependencies (as hinted by hack/lint-depdendencies.sh): github.com/cilium/ebpf v0.5.0 github.com/containerd/console v1.0.2 github.com/coreos/go-systemd/v22 v22.3.1 github.com/godbus/dbus/v5 v5.0.4 github.com/moby/sys/mountinfo v0.4.1 golang.org/x/sys v0.0.0-20210426230700-d19ff857e887 github.com/google/go-cmp v0.5.4 github.com/kr/pretty v0.2.1 github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417 Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
83 lines
2.3 KiB
Go
83 lines
2.3 KiB
Go
// +build linux
|
|
|
|
package libcontainer
|
|
|
|
import (
|
|
"path/filepath"
|
|
"unsafe"
|
|
|
|
"github.com/opencontainers/runc/libcontainer/cgroups/fscommon"
|
|
"github.com/pkg/errors"
|
|
"github.com/sirupsen/logrus"
|
|
"golang.org/x/sys/unix"
|
|
)
|
|
|
|
func registerMemoryEventV2(cgDir, evName, cgEvName string) (<-chan struct{}, error) {
|
|
fd, err := unix.InotifyInit()
|
|
if err != nil {
|
|
return nil, errors.Wrap(err, "unable to init inotify")
|
|
}
|
|
// watching oom kill
|
|
evFd, err := unix.InotifyAddWatch(fd, filepath.Join(cgDir, evName), unix.IN_MODIFY)
|
|
if err != nil {
|
|
unix.Close(fd)
|
|
return nil, errors.Wrap(err, "unable to add inotify watch")
|
|
}
|
|
// Because no `unix.IN_DELETE|unix.IN_DELETE_SELF` event for cgroup file system, so watching all process exited
|
|
cgFd, err := unix.InotifyAddWatch(fd, filepath.Join(cgDir, cgEvName), unix.IN_MODIFY)
|
|
if err != nil {
|
|
unix.Close(fd)
|
|
return nil, errors.Wrap(err, "unable to add inotify watch")
|
|
}
|
|
ch := make(chan struct{})
|
|
go func() {
|
|
var (
|
|
buffer [unix.SizeofInotifyEvent + unix.PathMax + 1]byte
|
|
offset uint32
|
|
)
|
|
defer func() {
|
|
unix.Close(fd)
|
|
close(ch)
|
|
}()
|
|
|
|
for {
|
|
n, err := unix.Read(fd, buffer[:])
|
|
if err != nil {
|
|
logrus.Warnf("unable to read event data from inotify, got error: %v", err)
|
|
return
|
|
}
|
|
if n < unix.SizeofInotifyEvent {
|
|
logrus.Warnf("we should read at least %d bytes from inotify, but got %d bytes.", unix.SizeofInotifyEvent, n)
|
|
return
|
|
}
|
|
offset = 0
|
|
for offset <= uint32(n-unix.SizeofInotifyEvent) {
|
|
rawEvent := (*unix.InotifyEvent)(unsafe.Pointer(&buffer[offset]))
|
|
offset += unix.SizeofInotifyEvent + uint32(rawEvent.Len)
|
|
if rawEvent.Mask&unix.IN_MODIFY != unix.IN_MODIFY {
|
|
continue
|
|
}
|
|
switch int(rawEvent.Wd) {
|
|
case evFd:
|
|
oom, err := fscommon.GetValueByKey(cgDir, evName, "oom_kill")
|
|
if err != nil || oom > 0 {
|
|
ch <- struct{}{}
|
|
}
|
|
case cgFd:
|
|
pids, err := fscommon.GetValueByKey(cgDir, cgEvName, "populated")
|
|
if err != nil || pids == 0 {
|
|
return
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}()
|
|
return ch, nil
|
|
}
|
|
|
|
// notifyOnOOMV2 returns channel on which you can expect event about OOM,
|
|
// if process died without OOM this channel will be closed.
|
|
func notifyOnOOMV2(path string) (<-chan struct{}, error) {
|
|
return registerMemoryEventV2(path, "memory.events", "cgroup.events")
|
|
}
|