forked from kata-containers/runtime
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add rootless package from containers/libpod
Add rootless package to kata in order to include some rootless functionalities including: 1. Determining whether an exectution is being ran rootless or not, 2. Get the rootless UID of a process, and 3. Get the rootless runtime directory for nonroot users. Signed-off-by: Gabi Beyer <[email protected]>
- Loading branch information
Gabi Beyer
committed
Jun 25, 2019
1 parent
829ac72
commit 1a26b16
Showing
2 changed files
with
116 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
#define _GNU_SOURCE | ||
#include <sys/types.h> | ||
|
||
static uid_t rootless_uid_init; | ||
static gid_t rootless_gid_init; | ||
|
||
uid_t | ||
rootless_uid () | ||
{ | ||
return rootless_uid_init; | ||
} | ||
|
||
uid_t | ||
rootless_gid () | ||
{ | ||
return rootless_gid_init; | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
package rootless | ||
|
||
import ( | ||
"fmt" | ||
"os" | ||
"path/filepath" | ||
"strconv" | ||
"sync" | ||
"syscall" | ||
|
||
"github.com/pkg/errors" | ||
) | ||
|
||
/* | ||
#include <sys/types.h> | ||
extern uid_t rootless_uid(); | ||
extern uid_t rootless_gid(); | ||
*/ | ||
import "C" | ||
|
||
var ( | ||
isRootlessOnce sync.Once | ||
isRootless bool | ||
|
||
rootlessRuntimeDirOnce sync.Once | ||
rootlessRuntimeDir string | ||
) | ||
|
||
// IsRootless tells us if we are running in rootless mode | ||
func IsRootless() bool { | ||
isRootlessOnce.Do(func() { | ||
rootlessUIDInit := int(C.rootless_uid()) | ||
rootlessGIDInit := int(C.rootless_gid()) | ||
if rootlessUIDInit != 0 { | ||
// This happens if we joined the user+mount namespace as part of | ||
os.Setenv("_CONTAINERS_USERNS_CONFIGURED", "done") | ||
os.Setenv("_CONTAINERS_ROOTLESS_UID", fmt.Sprintf("%d", rootlessUIDInit)) | ||
os.Setenv("_CONTAINERS_ROOTLESS_GID", fmt.Sprintf("%d", rootlessGIDInit)) | ||
} | ||
isRootless = os.Geteuid() != 0 || os.Getenv("_CONTAINERS_USERNS_CONFIGURED") != "" | ||
}) | ||
return isRootless | ||
} | ||
|
||
// GetRootlessUID returns the UID of the user in the parent userNS | ||
func GetRootlessUID() int { | ||
uidEnv := os.Getenv("_CONTAINERS_ROOTLESS_UID") | ||
if uidEnv != "" { | ||
u, _ := strconv.Atoi(uidEnv) | ||
return u | ||
} | ||
return os.Geteuid() | ||
} | ||
|
||
// GetRootlessRuntimeDir returns the runtime directory when running as non root | ||
func GetRootlessRuntimeDir() (string, error) { | ||
var rootlessRuntimeDirError error | ||
|
||
rootlessRuntimeDirOnce.Do(func() { | ||
runtimeDir := os.Getenv("XDG_RUNTIME_DIR") | ||
uid := fmt.Sprintf("%d", GetRootlessUID()) | ||
if runtimeDir == "" { | ||
tmpDir := filepath.Join("/run", "user", uid) | ||
os.MkdirAll(tmpDir, 0700) | ||
st, err := os.Stat(tmpDir) | ||
if err == nil && int(st.Sys().(*syscall.Stat_t).Uid) == os.Geteuid() && st.Mode().Perm() == 0700 { | ||
runtimeDir = tmpDir | ||
} | ||
} | ||
if runtimeDir == "" { | ||
tmpDir := filepath.Join(os.TempDir(), fmt.Sprintf("run-%s", uid)) | ||
os.MkdirAll(tmpDir, 0700) | ||
st, err := os.Stat(tmpDir) | ||
if err == nil && int(st.Sys().(*syscall.Stat_t).Uid) == os.Geteuid() && st.Mode().Perm() == 0700 { | ||
runtimeDir = tmpDir | ||
} | ||
} | ||
if runtimeDir == "" { | ||
home := os.Getenv("HOME") | ||
if home == "" { | ||
rootlessRuntimeDirError = fmt.Errorf("neither XDG_RUNTIME_DIR nor HOME was set non-empty") | ||
return | ||
} | ||
resolvedHome, err := filepath.EvalSymlinks(home) | ||
if err != nil { | ||
rootlessRuntimeDirError = errors.Wrapf(err, "cannot resolve %s", home) | ||
return | ||
} | ||
runtimeDir = filepath.Join(resolvedHome, "rundir") | ||
} | ||
rootlessRuntimeDir = runtimeDir | ||
}) | ||
|
||
if rootlessRuntimeDirError != nil { | ||
return "", rootlessRuntimeDirError | ||
} | ||
return rootlessRuntimeDir, nil | ||
} |