runc icon indicating copy to clipboard operation
runc copied to clipboard

runc aways open "/proc/sys/kernel/cap_last_cap"

Open ningmingxiao opened this issue 1 year ago • 5 comments

Description

runc aways open "/proc/sys/kernel/cap_last_cap" because it it done it init().

func init() {
	var hdr capHeader
	capget(&hdr, nil)
	capVers = hdr.version

	if initLastCap() == nil {
		CAP_LAST_CAP = capLastCap
		if capLastCap > 31 {
			capUpperMask = (uint32(1) << (uint(capLastCap) - 31)) - 1
		} else {
			capUpperMask = 0
		}
	}
}

func initLastCap() error {
	if capLastCap != 0 {
		return nil
	}

	f, err := os.Open("/proc/sys/kernel/cap_last_cap")
	if err != nil {
		return err
	}
	defer f.Close()

	var b []byte = make([]byte, 11)
	_, err = f.Read(b)
	if err != nil {
		return err
	}

	fmt.Sscanf(string(b), "%d", &capLastCap)

	return nil
}

Steps to reproduce the issue

1.runc --help will read /proc/sys/kernel/cap_last_cap

Describe the results you received and expected

read /proc/sys/kernel/cap_last_cap when needed

What version of runc are you using?

1.1.12

Host OS information

linux

Host kernel information

any

ningmingxiao avatar Jul 22 '24 02:07 ningmingxiao

ping @lifubang @kolyshkin

ningmingxiao avatar Jul 22 '24 02:07 ningmingxiao

This is a bug in https://github.com/syndtr/gocapability. You would just need to switch to using sync.Once.

EDIT: Ah, you already made a bug (syndtr/gocapability#26). Please link related bugs so they're easier to find.

cyphar avatar Jul 22 '24 06:07 cyphar

this library hasn't been updated for a long time. maybe nobody will maintain it. Can we move it to github.com/opencontainers/runc/libcontainer/capabilities ? use sync.Once is not a good idea. I want use it only when we need it. if use sync.Once runc version also call it.

ningmingxiao avatar Jul 22 '24 06:07 ningmingxiao

I mean to do sync.Once like this (which is what we usually do elsewhere in runc):

var (
  someBoolOnce sync.Once
  someBool bool
)

func getSomeBool() bool {
  someBoolOnce.Do(func() { ... })
  return someBool
}

cyphar avatar Jul 22 '24 06:07 cyphar

A slightly more modern way is to use sync.OnceValue. For usage example, see #4358.

Alas there's no way to stop init() functions from vendored packages to be run at startup.

Re github.com/syndtr/gocapability, I have 4 easy-to-review PRs in there opened Feb 2023, and it seems the original maintainer is not interested. Guess it's time to fork it.

kolyshkin avatar Jul 23 '24 00:07 kolyshkin