From 26d8ff4d7f568cc008ae98f8b111a7d09178c391 Mon Sep 17 00:00:00 2001 From: "Zheao.Li" Date: Fri, 20 Oct 2023 20:25:10 +0800 Subject: [PATCH] carry #3126: linux: Support setting execution domain via linux personality Signed-off-by: Zheao.Li --- libcontainer/configs/config.go | 3 +++ libcontainer/configs/config_linux.go | 13 +++++++++++++ libcontainer/specconv/spec_linux.go | 20 ++++++++++++++++++++ libcontainer/system/linux.go | 10 ++++++++++ 4 files changed, 46 insertions(+) diff --git a/libcontainer/configs/config.go b/libcontainer/configs/config.go index 1ece49c3732..c6495d6f1e0 100644 --- a/libcontainer/configs/config.go +++ b/libcontainer/configs/config.go @@ -223,6 +223,9 @@ type Config struct { // Scheduler represents the scheduling attributes for a process. Scheduler *Scheduler `json:"scheduler,omitempty"` + + // Personality contains configuration for the Linux personality syscall. + Personality *LinuxPersonality `json:"personality,omitempty"` } // Scheduler is based on the Linux sched_setattr(2) syscall. diff --git a/libcontainer/configs/config_linux.go b/libcontainer/configs/config_linux.go index 4e58bb39630..c3ce7bbf5cf 100644 --- a/libcontainer/configs/config_linux.go +++ b/libcontainer/configs/config_linux.go @@ -9,6 +9,19 @@ var ( errNoGroupMap = errors.New("User namespaces enabled, but no group mapping found.") ) +// Please check https://man7.org/linux/man-pages/man2/personality.2.html for const details. +// https://raw.githubusercontent.com/torvalds/linux/master/include/uapi/linux/personality.h +const ( + PER_LINUX = 0x0000 + PER_LINUX32 = 0x0008 +) + +type LinuxPersonality struct { + // Domain for the personality + // can only contain values "LINUX" and "LINUX32" + Domain int `json:"domain"` +} + // HostUID gets the translated uid for the process on host which could be // different when user namespaces are enabled. func (c Config) HostUID(containerId int) (int, error) { diff --git a/libcontainer/specconv/spec_linux.go b/libcontainer/specconv/spec_linux.go index c5553832776..5c8fe2fdc10 100644 --- a/libcontainer/specconv/spec_linux.go +++ b/libcontainer/specconv/spec_linux.go @@ -436,6 +436,15 @@ func CreateLibcontainerConfig(opts *CreateOpts) (*configs.Config, error) { MemBwSchema: spec.Linux.IntelRdt.MemBwSchema, } } + if spec.Linux.Personality != nil { + domain, err := getLinuxPersonalityFromStr(string(spec.Linux.Personality.Domain)) + if err != nil { + return nil, err + } + config.Personality = &configs.LinuxPersonality{ + Domain: domain, + } + } } // Set the host UID that should own the container's cgroup. @@ -573,6 +582,17 @@ func checkPropertyName(s string) error { return nil } +// getLinuxPersonalityFromStr converts the string domain received from spec to equivalent integer. +func getLinuxPersonalityFromStr(domain string) (int, error) { + // defaults to PER_LINUX + if domain == "LINUX32" { + return configs.PER_LINUX32, nil + } else if domain == "LINUX" { + return configs.PER_LINUX, nil + } + return -1, fmt.Errorf("invalid personality domain %s", domain) +} + // Some systemd properties are documented as having "Sec" suffix // (e.g. TimeoutStopSec) but are expected to have "USec" suffix // here, so let's provide conversion to improve compatibility. diff --git a/libcontainer/system/linux.go b/libcontainer/system/linux.go index 318b6edfe81..113106fad01 100644 --- a/libcontainer/system/linux.go +++ b/libcontainer/system/linux.go @@ -214,3 +214,13 @@ func Copy(dst io.Writer, src io.Reader) (copied int64, err error) { fallback: return io.Copy(dst, src) } + +// SetLinuxPersonality sets the Linux execution personality. For more information see the personality syscall documentation. +// checkout getLinuxPersonalityFromStr() from libcontainer/specconv/spec_linux.go for type conversion. +func SetLinuxPersonality(persona int) error { + _, _, errno := syscall.Syscall(syscall.SYS_PERSONALITY, uintptr(persona), 0, 0) + if errno != 0 { + return &os.SyscallError{Syscall: "set_personality", Err: errno} + } + return nil +}