rootless: store also the original GID in the host

Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
This commit is contained in:
Giuseppe Scrivano
2019-05-23 22:28:38 +02:00
parent 1dbb27365a
commit 6df320c391
3 changed files with 41 additions and 0 deletions

View File

@ -40,6 +40,7 @@ static const char *_unprivileged_user_namespaces = "/proc/sys/kernel/unprivilege
static int open_files_max_fd; static int open_files_max_fd;
fd_set open_files_set; fd_set open_files_set;
static uid_t rootless_uid_init; static uid_t rootless_uid_init;
static gid_t rootless_gid_init;
static int static int
syscall_setresuid (uid_t ruid, uid_t euid, uid_t suid) syscall_setresuid (uid_t ruid, uid_t euid, uid_t suid)
@ -59,6 +60,12 @@ rootless_uid ()
return rootless_uid_init; return rootless_uid_init;
} }
uid_t
rootless_gid ()
{
return rootless_gid_init;
}
static void static void
do_pause () do_pause ()
{ {
@ -224,6 +231,7 @@ static void __attribute__((constructor)) init()
long pid; long pid;
char buf[12]; char buf[12];
uid_t uid; uid_t uid;
gid_t gid;
char path[PATH_MAX]; char path[PATH_MAX];
const char *const suffix = "/libpod/pause.pid"; const char *const suffix = "/libpod/pause.pid";
char *cwd = getcwd (NULL, 0); char *cwd = getcwd (NULL, 0);
@ -263,6 +271,7 @@ static void __attribute__((constructor)) init()
} }
uid = geteuid (); uid = geteuid ();
gid = getegid ();
sprintf (path, "/proc/%d/ns/user", pid); sprintf (path, "/proc/%d/ns/user", pid);
fd = open (path, O_RDONLY); fd = open (path, O_RDONLY);
@ -310,6 +319,7 @@ static void __attribute__((constructor)) init()
free (cwd); free (cwd);
rootless_uid_init = uid; 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 (); pid_t ppid = getpid ();
char uid[16]; char uid[16];
char gid[16];
char **argv; char **argv;
int pid; int pid;
char *cwd = getcwd (NULL, 0); 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 (uid, "%d", geteuid ());
sprintf (gid, "%d", getegid ());
argv = get_cmd_line_args (ppid); argv = get_cmd_line_args (ppid);
if (argv == NULL) 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_USERNS_CONFIGURED", "init", 1);
setenv ("_CONTAINERS_ROOTLESS_UID", uid, 1); setenv ("_CONTAINERS_ROOTLESS_UID", uid, 1);
setenv ("_CONTAINERS_ROOTLESS_GID", gid, 1);
if (prctl (PR_SET_PDEATHSIG, SIGTERM, 0, 0, 0) < 0) 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 (); pid_t ppid = getpid ();
char **argv; char **argv;
char uid[16]; char uid[16];
char gid[16];
char *listen_fds = NULL; char *listen_fds = NULL;
char *listen_pid = NULL; char *listen_pid = NULL;
bool do_socket_activation = false; 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 (uid, "%d", geteuid ());
sprintf (gid, "%d", getegid ());
pid = syscall_clone (CLONE_NEWUSER|CLONE_NEWNS|SIGCHLD, NULL); pid = syscall_clone (CLONE_NEWUSER|CLONE_NEWNS|SIGCHLD, NULL);
if (pid < 0) 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_USERNS_CONFIGURED", "init", 1);
setenv ("_CONTAINERS_ROOTLESS_UID", uid, 1); setenv ("_CONTAINERS_ROOTLESS_UID", uid, 1);
setenv ("_CONTAINERS_ROOTLESS_GID", gid, 1);
do do
ret = read (ready, &b, 1) < 0; ret = read (ready, &b, 1) < 0;

View File

@ -25,6 +25,7 @@ import (
#cgo remoteclient CFLAGS: -DDISABLE_JOIN_SHORTCUT #cgo remoteclient CFLAGS: -DDISABLE_JOIN_SHORTCUT
#include <stdlib.h> #include <stdlib.h>
extern uid_t rootless_uid(); 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(int ready, char *pause_pid_file_path);
extern int reexec_in_user_namespace_wait(int pid); extern int reexec_in_user_namespace_wait(int pid);
extern int reexec_userns_join(int userns, int mountns, char *pause_pid_file_path); extern int reexec_userns_join(int userns, int mountns, char *pause_pid_file_path);
@ -49,10 +50,12 @@ var (
func IsRootless() bool { func IsRootless() bool {
isRootlessOnce.Do(func() { isRootlessOnce.Do(func() {
rootlessUIDInit := int(C.rootless_uid()) rootlessUIDInit := int(C.rootless_uid())
rootlessGIDInit := int(C.rootless_gid())
if rootlessUIDInit != 0 { if rootlessUIDInit != 0 {
// This happens if we joined the user+mount namespace as part of // This happens if we joined the user+mount namespace as part of
os.Setenv("_CONTAINERS_USERNS_CONFIGURED", "done") os.Setenv("_CONTAINERS_USERNS_CONFIGURED", "done")
os.Setenv("_CONTAINERS_ROOTLESS_UID", fmt.Sprintf("%d", rootlessUIDInit)) 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") != "" isRootless = os.Geteuid() != 0 || os.Getenv("_CONTAINERS_USERNS_CONFIGURED") != ""
}) })
@ -69,6 +72,23 @@ func GetRootlessUID() int {
return os.Geteuid() 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 { func tryMappingTool(tool string, pid int, hostID int, mappings []idtools.IDMap) error {
path, err := exec.LookPath(tool) path, err := exec.LookPath(tool)
if err != nil { if err != nil {

View File

@ -24,6 +24,11 @@ func GetRootlessUID() int {
return -1 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 // 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 // namespace of the specified PID without looking up its parent. Useful to join directly
// the conmon process. It is a convenience function for JoinUserAndMountNSWithOpts // the conmon process. It is a convenience function for JoinUserAndMountNSWithOpts