mirror of
https://github.com/aljazceru/kata-containers.git
synced 2025-12-25 10:04:20 +01:00
`rangeUID` should be parsed as ids[2] rather than ids[1] Fixes: #2173 Signed-off-by: Li Yuxuan <liyuxuan04@baidu.com>
124 lines
2.8 KiB
Go
124 lines
2.8 KiB
Go
// Copyright (c) 2019 Intel Corporation
|
|
//
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
//
|
|
|
|
package rootless
|
|
|
|
import (
|
|
"bufio"
|
|
"context"
|
|
"io"
|
|
"os"
|
|
"strconv"
|
|
"strings"
|
|
"sync"
|
|
|
|
"github.com/pkg/errors"
|
|
"github.com/sirupsen/logrus"
|
|
)
|
|
|
|
var (
|
|
// initRootless states whether the isRootless variable
|
|
// has been set yet
|
|
initRootless bool
|
|
|
|
// isRootless states whether execution is rootless or not
|
|
isRootless bool
|
|
|
|
// lock for the initRootless and isRootless variables
|
|
rLock sync.Mutex
|
|
|
|
// XDG_RUNTIME_DIR defines the base directory relative to
|
|
// which user-specific non-essential runtime files are stored.
|
|
rootlessDir = os.Getenv("XDG_RUNTIME_DIR")
|
|
|
|
// uidMapPath defines the location of the uid_map file to
|
|
// determine whether a user is root or not
|
|
uidMapPath = "/proc/self/uid_map"
|
|
|
|
rootlessLog = logrus.WithFields(logrus.Fields{
|
|
"source": "rootless",
|
|
})
|
|
)
|
|
|
|
// SetLogger sets up a logger for the rootless pkg
|
|
func SetLogger(ctx context.Context, logger *logrus.Entry) {
|
|
fields := rootlessLog.Data
|
|
rootlessLog = logger.WithFields(fields)
|
|
}
|
|
|
|
// setRootless reads a uid_map file, compares the UID of the
|
|
// user inside the container vs on the host. If the host UID
|
|
// is not root, but the container ID is, it can be determined
|
|
// the user is running rootlessly.
|
|
func setRootless() error {
|
|
initRootless = true
|
|
file, err := os.Open(uidMapPath)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer file.Close()
|
|
|
|
buf := bufio.NewReader(file)
|
|
for {
|
|
line, _, err := buf.ReadLine()
|
|
if err != nil {
|
|
if err == io.EOF {
|
|
return nil
|
|
}
|
|
return err
|
|
}
|
|
if line == nil {
|
|
return nil
|
|
}
|
|
|
|
var parseError = errors.Errorf("Failed to parse uid map file %s", uidMapPath)
|
|
// if the container id (id[0]) is 0 (root inside the container)
|
|
// has a mapping to the host id (id[1]) that is not root, then
|
|
// it can be determined that the host user is running rootless
|
|
ids := strings.Fields(string(line))
|
|
// do some sanity checks
|
|
if len(ids) != 3 {
|
|
return parseError
|
|
}
|
|
userNSUid, err := strconv.ParseUint(ids[0], 10, 0)
|
|
if err != nil {
|
|
return parseError
|
|
}
|
|
hostUID, err := strconv.ParseUint(ids[1], 10, 0)
|
|
if err != nil {
|
|
return parseError
|
|
}
|
|
rangeUID, err := strconv.ParseUint(ids[2], 10, 0)
|
|
if err != nil || rangeUID == 0 {
|
|
return parseError
|
|
}
|
|
|
|
if userNSUid == 0 && hostUID != 0 {
|
|
rootlessLog.Info("Running as rootless")
|
|
isRootless = true
|
|
return nil
|
|
}
|
|
}
|
|
}
|
|
|
|
// IsRootless states whether kata is being ran with root or not
|
|
func IsRootless() bool {
|
|
rLock.Lock()
|
|
if !initRootless {
|
|
err := setRootless()
|
|
if err != nil {
|
|
rootlessLog.WithError(err).Error("Unable to determine if running rootless")
|
|
}
|
|
}
|
|
rLock.Unlock()
|
|
return isRootless
|
|
}
|
|
|
|
// GetRootlessDir returns the path to the location for rootless
|
|
// container and sandbox storage
|
|
func GetRootlessDir() string {
|
|
return rootlessDir
|
|
}
|