rootless: use functionalities from c/storage

Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
This commit is contained in:
Giuseppe Scrivano
2023-11-10 21:57:50 +01:00
parent fbd1ba68f6
commit d636ce8d76

View File

@ -45,6 +45,23 @@ const (
numSig = 65 // max number of signals numSig = 65 // max number of signals
) )
func init() {
rootlessUIDInit := int(C.rootless_uid())
rootlessGIDInit := int(C.rootless_gid())
if rootlessUIDInit != 0 {
// we need this if we joined the user+mount namespace from the C code.
if err := os.Setenv("_CONTAINERS_USERNS_CONFIGURED", "done"); err != nil {
logrus.Errorf("Failed to set environment variable %s as %s", "_CONTAINERS_USERNS_CONFIGURED", "done")
}
if err := os.Setenv("_CONTAINERS_ROOTLESS_UID", strconv.Itoa(rootlessUIDInit)); err != nil {
logrus.Errorf("Failed to set environment variable %s as %d", "_CONTAINERS_ROOTLESS_UID", rootlessUIDInit)
}
if err := os.Setenv("_CONTAINERS_ROOTLESS_GID", strconv.Itoa(rootlessGIDInit)); err != nil {
logrus.Errorf("Failed to set environment variable %s as %d", "_CONTAINERS_ROOTLESS_GID", rootlessGIDInit)
}
}
}
func runInUser() error { func runInUser() error {
return os.Setenv("_CONTAINERS_USERNS_CONFIGURED", "done") return os.Setenv("_CONTAINERS_USERNS_CONFIGURED", "done")
} }
@ -56,60 +73,21 @@ var (
// IsRootless tells us if we are running in rootless mode // IsRootless tells us if we are running in rootless mode
func IsRootless() bool { func IsRootless() bool {
isRootlessOnce.Do(func() { // unshare.IsRootless() is used to check if a user namespace is required.
rootlessUIDInit := int(C.rootless_uid()) // Here we need to make sure that nested podman instances act
rootlessGIDInit := int(C.rootless_gid()) // as if they have root privileges and pick paths on the host
if rootlessUIDInit != 0 { // that would normally be used for root.
// This happens if we joined the user+mount namespace as part of return unshare.IsRootless() && unshare.GetRootlessUID() > 0
if err := os.Setenv("_CONTAINERS_USERNS_CONFIGURED", "done"); err != nil {
logrus.Errorf("Failed to set environment variable %s as %s", "_CONTAINERS_USERNS_CONFIGURED", "done")
}
if err := os.Setenv("_CONTAINERS_ROOTLESS_UID", strconv.Itoa(rootlessUIDInit)); err != nil {
logrus.Errorf("Failed to set environment variable %s as %d", "_CONTAINERS_ROOTLESS_UID", rootlessUIDInit)
}
if err := os.Setenv("_CONTAINERS_ROOTLESS_GID", strconv.Itoa(rootlessGIDInit)); err != nil {
logrus.Errorf("Failed to set environment variable %s as %d", "_CONTAINERS_ROOTLESS_GID", rootlessGIDInit)
}
}
isRootless = os.Geteuid() != 0 || os.Getenv("_CONTAINERS_USERNS_CONFIGURED") != ""
if !isRootless {
hasCapSysAdmin, err := unshare.HasCapSysAdmin()
if err != nil {
logrus.Warnf("Failed to read CAP_SYS_ADMIN presence for the current process")
}
if err == nil && !hasCapSysAdmin {
isRootless = true
}
}
})
return isRootless
} }
// GetRootlessUID returns the UID of the user in the parent userNS // GetRootlessUID returns the UID of the user in the parent userNS
func GetRootlessUID() int { func GetRootlessUID() int {
uidEnv := os.Getenv("_CONTAINERS_ROOTLESS_UID") return unshare.GetRootlessUID()
if uidEnv != "" {
u, _ := strconv.Atoi(uidEnv)
return u
}
return os.Geteuid()
} }
// GetRootlessGID returns the GID of the user in the parent userNS // GetRootlessGID returns the GID of the user in the parent userNS
func GetRootlessGID() int { func GetRootlessGID() int {
gidEnv := os.Getenv("_CONTAINERS_ROOTLESS_GID") return unshare.GetRootlessGID()
if gidEnv != "" {
u, _ := strconv.Atoi(gidEnv)
return u
}
/* If the _CONTAINERS_ROOTLESS_UID is set, assume the gid==uid. */
uidEnv := os.Getenv("_CONTAINERS_ROOTLESS_UID")
if uidEnv != "" {
u, _ := strconv.Atoi(uidEnv)
return u
}
return os.Getegid()
} }
func tryMappingTool(uid bool, pid int, hostID int, mappings []idtools.IDMap) error { func tryMappingTool(uid bool, pid int, hostID int, mappings []idtools.IDMap) error {