mirror of
https://github.com/containers/podman.git
synced 2025-10-17 19:24:04 +08:00
rootless: add new function to join existing namespace
Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com> Closes: #1371 Approved by: rhatdan
This commit is contained in:

committed by
Atomic Bot

parent
eb5fdebc84
commit
1789242933
@ -83,7 +83,37 @@ get_cmd_line_args (pid_t pid)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
reexec_in_user_namespace(int ready)
|
reexec_userns_join (int userns)
|
||||||
|
{
|
||||||
|
pid_t ppid = getpid ();
|
||||||
|
char uid[16];
|
||||||
|
char **argv;
|
||||||
|
int pid;
|
||||||
|
|
||||||
|
sprintf (uid, "%d", geteuid ());
|
||||||
|
|
||||||
|
argv = get_cmd_line_args (ppid);
|
||||||
|
if (argv == NULL)
|
||||||
|
_exit (EXIT_FAILURE);
|
||||||
|
|
||||||
|
pid = fork ();
|
||||||
|
if (pid)
|
||||||
|
return pid;
|
||||||
|
|
||||||
|
setenv ("_LIBPOD_USERNS_CONFIGURED", "init", 1);
|
||||||
|
setenv ("_LIBPOD_ROOTLESS_UID", uid, 1);
|
||||||
|
|
||||||
|
if (setns (userns, 0) < 0)
|
||||||
|
_exit (EXIT_FAILURE);
|
||||||
|
close (userns);
|
||||||
|
|
||||||
|
execvp (argv[0], argv);
|
||||||
|
|
||||||
|
_exit (EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
reexec_in_user_namespace (int ready)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
|
@ -23,6 +23,7 @@ import (
|
|||||||
/*
|
/*
|
||||||
extern int reexec_in_user_namespace(int ready);
|
extern int reexec_in_user_namespace(int ready);
|
||||||
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);
|
||||||
*/
|
*/
|
||||||
import "C"
|
import "C"
|
||||||
|
|
||||||
@ -84,6 +85,32 @@ func tryMappingTool(tool string, pid int, hostID int, mappings []idtools.IDMap)
|
|||||||
return cmd.Run()
|
return cmd.Run()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// JoinNS re-exec podman in a new userNS and join the user namespace of the specified
|
||||||
|
// PID.
|
||||||
|
func JoinNS(pid uint) (bool, int, error) {
|
||||||
|
if os.Getuid() == 0 || os.Getenv("_LIBPOD_USERNS_CONFIGURED") != "" {
|
||||||
|
return false, -1, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
userNS, err := GetUserNSForPid(pid)
|
||||||
|
if err != nil {
|
||||||
|
return false, -1, err
|
||||||
|
}
|
||||||
|
defer userNS.Close()
|
||||||
|
|
||||||
|
pidC := C.reexec_userns_join(C.int(userNS.Fd()))
|
||||||
|
if int(pidC) < 0 {
|
||||||
|
return false, -1, errors.Errorf("cannot re-exec process")
|
||||||
|
}
|
||||||
|
|
||||||
|
ret := C.reexec_in_user_namespace_wait(pidC)
|
||||||
|
if ret < 0 {
|
||||||
|
return false, -1, errors.New("error waiting for the re-exec process")
|
||||||
|
}
|
||||||
|
|
||||||
|
return true, int(ret), nil
|
||||||
|
}
|
||||||
|
|
||||||
// BecomeRootInUserNS re-exec podman in a new userNS. It returns whether podman was re-executed
|
// BecomeRootInUserNS re-exec podman in a new userNS. It returns whether podman was re-executed
|
||||||
// into a new user namespace and the return code from the re-executed podman process.
|
// into a new user namespace and the return code from the re-executed podman process.
|
||||||
// If podman was re-executed the caller needs to propagate the error code returned by the child
|
// If podman was re-executed the caller needs to propagate the error code returned by the child
|
||||||
@ -183,7 +210,7 @@ func BecomeRootInUserNS() (bool, int, error) {
|
|||||||
|
|
||||||
ret := C.reexec_in_user_namespace_wait(pidC)
|
ret := C.reexec_in_user_namespace_wait(pidC)
|
||||||
if ret < 0 {
|
if ret < 0 {
|
||||||
return false, -1, errors.Wrapf(err, "error waiting for the re-exec process")
|
return false, -1, errors.New("error waiting for the re-exec process")
|
||||||
}
|
}
|
||||||
|
|
||||||
return true, int(ret), nil
|
return true, int(ret), nil
|
||||||
|
@ -33,6 +33,12 @@ func SkipStorageSetup() bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// JoinNS re-exec podman in a new userNS and join the user namespace of the specified
|
||||||
|
// PID.
|
||||||
|
func JoinNS(pid uint) (bool, int, error) {
|
||||||
|
return false, -1, errors.New("this function is not supported on this os")
|
||||||
|
}
|
||||||
|
|
||||||
// GetUserNSForPid returns an open FD for the first direct child user namespace that created the process
|
// GetUserNSForPid returns an open FD for the first direct child user namespace that created the process
|
||||||
func GetUserNSForPid(pid uint) (*os.File, error) {
|
func GetUserNSForPid(pid uint) (*os.File, error) {
|
||||||
return nil, errors.New("this function is not supported on this os")
|
return nil, errors.New("this function is not supported on this os")
|
||||||
|
Reference in New Issue
Block a user