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  }