github.com/kaisenlinux/docker@v0.0.0-20230510090727-ea55db55fac7/engine/profiles/seccomp/kernel_linux.go (about) 1 package seccomp 2 3 import ( 4 "bytes" 5 "fmt" 6 "sync" 7 8 "golang.org/x/sys/unix" 9 ) 10 11 var ( 12 currentKernelVersion *KernelVersion 13 kernelVersionError error 14 once sync.Once 15 ) 16 17 // getKernelVersion gets the current kernel version. 18 func getKernelVersion() (*KernelVersion, error) { 19 once.Do(func() { 20 var uts unix.Utsname 21 if err := unix.Uname(&uts); err != nil { 22 return 23 } 24 // Remove the \x00 from the release for Atoi to parse correctly 25 currentKernelVersion, kernelVersionError = parseRelease(string(uts.Release[:bytes.IndexByte(uts.Release[:], 0)])) 26 }) 27 return currentKernelVersion, kernelVersionError 28 } 29 30 // parseRelease parses a string and creates a KernelVersion based on it. 31 func parseRelease(release string) (*KernelVersion, error) { 32 var version = KernelVersion{} 33 34 // We're only make sure we get the "kernel" and "major revision". Sometimes we have 35 // 3.12.25-gentoo, but sometimes we just have 3.12-1-amd64. 36 _, err := fmt.Sscanf(release, "%d.%d", &version.Kernel, &version.Major) 37 if err != nil { 38 return nil, fmt.Errorf("failed to parse kernel version %q: %w", release, err) 39 } 40 return &version, nil 41 } 42 43 // kernelGreaterEqualThan checks if the host's kernel version is greater than, or 44 // equal to the given kernel version v. Only "kernel version" and "major revision" 45 // can be specified (e.g., "3.12") and will be taken into account, which means 46 // that 3.12.25-gentoo and 3.12-1-amd64 are considered equal (kernel: 3, major: 12). 47 func kernelGreaterEqualThan(minVersion KernelVersion) (bool, error) { 48 kv, err := getKernelVersion() 49 if err != nil { 50 return false, err 51 } 52 if kv.Kernel > minVersion.Kernel { 53 return true, nil 54 } 55 if kv.Kernel == minVersion.Kernel && kv.Major >= minVersion.Major { 56 return true, nil 57 } 58 return false, nil 59 }