nsenter: do not resolve path in nsexec context

With the addition of our new{uid,gid}map support, we used to call
execvp(3) from inside nsexec. This would mean that the path resolution
for the binaries would happen in nsexec. Move the resolution to the
initial setup code, and pass the absolute path to nsexec.

Signed-off-by: Aleksa Sarai <asarai@suse.de>
This commit is contained in:
Aleksa Sarai 2017-09-06 22:13:47 +10:00
parent 6097ce74d8
commit 969bb49cc3
No known key found for this signature in database
GPG Key ID: 9E18AA267DDB8DB4
2 changed files with 22 additions and 5 deletions

View File

@ -211,7 +211,7 @@ static int try_mapping_tool(const char *app, int pid, char *map, size_t map_len)
int child; int child;
/* /*
* If @app is NULL, execvp will segfault. Just check it here and bail (if * If @app is NULL, execve will segfault. Just check it here and bail (if
* we're in this path, the caller is already getting desparate and there * we're in this path, the caller is already getting desparate and there
* isn't a backup to this failing). This usually would be a configuration * isn't a backup to this failing). This usually would be a configuration
* or programming issue. * or programming issue.
@ -226,6 +226,7 @@ static int try_mapping_tool(const char *app, int pid, char *map, size_t map_len)
if (!child) { if (!child) {
#define MAX_ARGV 20 #define MAX_ARGV 20
char *argv[MAX_ARGV]; char *argv[MAX_ARGV];
char *envp[] = {NULL};
char pid_fmt[16]; char pid_fmt[16];
int argc = 0; int argc = 0;
char *next; char *next;
@ -252,8 +253,8 @@ static int try_mapping_tool(const char *app, int pid, char *map, size_t map_len)
map = next + strspn(next, "\n "); map = next + strspn(next, "\n ");
} }
execvp(app, argv); execve(app, argv, envp);
bail("failed to execvp"); bail("failed to execv");
} else { } else {
int status; int status;

View File

@ -7,6 +7,7 @@ import (
"fmt" "fmt"
"net" "net"
"os" "os"
"os/exec"
"path/filepath" "path/filepath"
"strconv" "strconv"
@ -35,6 +36,9 @@ func loadFactory(context *cli.Context) (libcontainer.Factory, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
// We default to cgroupfs, and can only use systemd if the system is a
// systemd box.
cgroupManager := libcontainer.Cgroupfs cgroupManager := libcontainer.Cgroupfs
if context.GlobalBool("systemd-cgroup") { if context.GlobalBool("systemd-cgroup") {
if systemd.UseSystemd() { if systemd.UseSystemd() {
@ -49,10 +53,22 @@ func loadFactory(context *cli.Context) (libcontainer.Factory, error) {
intelRdtManager = nil intelRdtManager = nil
} }
// We resolve the paths for {newuidmap,newgidmap} from the context of runc,
// to avoid doing a path lookup in the nsexec context. TODO: The binary
// names are not currently configurable.
newuidmap, err := exec.LookPath("newuidmap")
if err != nil {
newuidmap = ""
}
newgidmap, err := exec.LookPath("newgidmap")
if err != nil {
newgidmap = ""
}
return libcontainer.New(abs, cgroupManager, intelRdtManager, return libcontainer.New(abs, cgroupManager, intelRdtManager,
libcontainer.CriuPath(context.GlobalString("criu")), libcontainer.CriuPath(context.GlobalString("criu")),
libcontainer.NewuidmapPath("newuidmap"), libcontainer.NewuidmapPath(newuidmap),
libcontainer.NewgidmapPath("newgidmap")) libcontainer.NewgidmapPath(newgidmap))
} }
// getContainer returns the specified container instance by loading it from state // getContainer returns the specified container instance by loading it from state