mirror of
https://github.com/containers/podman.git
synced 2025-05-21 17:16:22 +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;
|
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;
|
||||||
|
@ -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 {
|
||||||
|
@ -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
|
||||||
|
Reference in New Issue
Block a user