mirror of
https://github.com/containers/podman.git
synced 2025-05-21 00:56:36 +08:00
rootless: store also the original GID in the host
Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
This commit is contained in:
@ -40,6 +40,7 @@ static const char *_unprivileged_user_namespaces = "/proc/sys/kernel/unprivilege
|
||||
static int open_files_max_fd;
|
||||
fd_set open_files_set;
|
||||
static uid_t rootless_uid_init;
|
||||
static gid_t rootless_gid_init;
|
||||
|
||||
static int
|
||||
syscall_setresuid (uid_t ruid, uid_t euid, uid_t suid)
|
||||
@ -59,6 +60,12 @@ rootless_uid ()
|
||||
return rootless_uid_init;
|
||||
}
|
||||
|
||||
uid_t
|
||||
rootless_gid ()
|
||||
{
|
||||
return rootless_gid_init;
|
||||
}
|
||||
|
||||
static void
|
||||
do_pause ()
|
||||
{
|
||||
@ -224,6 +231,7 @@ static void __attribute__((constructor)) init()
|
||||
long pid;
|
||||
char buf[12];
|
||||
uid_t uid;
|
||||
gid_t gid;
|
||||
char path[PATH_MAX];
|
||||
const char *const suffix = "/libpod/pause.pid";
|
||||
char *cwd = getcwd (NULL, 0);
|
||||
@ -263,6 +271,7 @@ static void __attribute__((constructor)) init()
|
||||
}
|
||||
|
||||
uid = geteuid ();
|
||||
gid = getegid ();
|
||||
|
||||
sprintf (path, "/proc/%d/ns/user", pid);
|
||||
fd = open (path, O_RDONLY);
|
||||
@ -310,6 +319,7 @@ static void __attribute__((constructor)) init()
|
||||
|
||||
free (cwd);
|
||||
rootless_uid_init = uid;
|
||||
rootless_gid_init = gid;
|
||||
}
|
||||
}
|
||||
|
||||
@ -440,6 +450,7 @@ reexec_userns_join (int userns, int mountns, char *pause_pid_file_path)
|
||||
{
|
||||
pid_t ppid = getpid ();
|
||||
char uid[16];
|
||||
char gid[16];
|
||||
char **argv;
|
||||
int pid;
|
||||
char *cwd = getcwd (NULL, 0);
|
||||
@ -451,6 +462,7 @@ reexec_userns_join (int userns, int mountns, char *pause_pid_file_path)
|
||||
}
|
||||
|
||||
sprintf (uid, "%d", geteuid ());
|
||||
sprintf (gid, "%d", getegid ());
|
||||
|
||||
argv = get_cmd_line_args (ppid);
|
||||
if (argv == NULL)
|
||||
@ -477,6 +489,7 @@ reexec_userns_join (int userns, int mountns, char *pause_pid_file_path)
|
||||
|
||||
setenv ("_CONTAINERS_USERNS_CONFIGURED", "init", 1);
|
||||
setenv ("_CONTAINERS_ROOTLESS_UID", uid, 1);
|
||||
setenv ("_CONTAINERS_ROOTLESS_GID", gid, 1);
|
||||
|
||||
if (prctl (PR_SET_PDEATHSIG, SIGTERM, 0, 0, 0) < 0)
|
||||
{
|
||||
@ -556,6 +569,7 @@ reexec_in_user_namespace (int ready, char *pause_pid_file_path)
|
||||
pid_t ppid = getpid ();
|
||||
char **argv;
|
||||
char uid[16];
|
||||
char gid[16];
|
||||
char *listen_fds = NULL;
|
||||
char *listen_pid = NULL;
|
||||
bool do_socket_activation = false;
|
||||
@ -577,6 +591,7 @@ reexec_in_user_namespace (int ready, char *pause_pid_file_path)
|
||||
}
|
||||
|
||||
sprintf (uid, "%d", geteuid ());
|
||||
sprintf (gid, "%d", getegid ());
|
||||
|
||||
pid = syscall_clone (CLONE_NEWUSER|CLONE_NEWNS|SIGCHLD, NULL);
|
||||
if (pid < 0)
|
||||
@ -621,6 +636,7 @@ reexec_in_user_namespace (int ready, char *pause_pid_file_path)
|
||||
|
||||
setenv ("_CONTAINERS_USERNS_CONFIGURED", "init", 1);
|
||||
setenv ("_CONTAINERS_ROOTLESS_UID", uid, 1);
|
||||
setenv ("_CONTAINERS_ROOTLESS_GID", gid, 1);
|
||||
|
||||
do
|
||||
ret = read (ready, &b, 1) < 0;
|
||||
|
@ -25,6 +25,7 @@ import (
|
||||
#cgo remoteclient CFLAGS: -DDISABLE_JOIN_SHORTCUT
|
||||
#include <stdlib.h>
|
||||
extern uid_t rootless_uid();
|
||||
extern uid_t rootless_gid();
|
||||
extern int reexec_in_user_namespace(int ready, char *pause_pid_file_path);
|
||||
extern int reexec_in_user_namespace_wait(int pid);
|
||||
extern int reexec_userns_join(int userns, int mountns, char *pause_pid_file_path);
|
||||
@ -49,10 +50,12 @@ var (
|
||||
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") != ""
|
||||
})
|
||||
@ -69,6 +72,23 @@ func GetRootlessUID() int {
|
||||
return os.Geteuid()
|
||||
}
|
||||
|
||||
// GetRootlessGID returns the GID of the user in the parent userNS
|
||||
func GetRootlessGID() int {
|
||||
gidEnv := os.Getenv("_CONTAINERS_ROOTLESS_GID")
|
||||
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(tool string, pid int, hostID int, mappings []idtools.IDMap) error {
|
||||
path, err := exec.LookPath(tool)
|
||||
if err != nil {
|
||||
|
@ -24,6 +24,11 @@ func GetRootlessUID() int {
|
||||
return -1
|
||||
}
|
||||
|
||||
// GetRootlessGID returns the GID of the user in the parent userNS
|
||||
func GetRootlessGID() int {
|
||||
return -1
|
||||
}
|
||||
|
||||
// JoinUserAndMountNS re-exec podman in a new userNS and join the user and mount
|
||||
// namespace of the specified PID without looking up its parent. Useful to join directly
|
||||
// the conmon process. It is a convenience function for JoinUserAndMountNSWithOpts
|
||||
|
Reference in New Issue
Block a user