diff --git a/libcontainer/init_linux.go b/libcontainer/init_linux.go index a24be276878..cfc8c931981 100644 --- a/libcontainer/init_linux.go +++ b/libcontainer/init_linux.go @@ -440,8 +440,7 @@ func syncParentSeccomp(pipe *os.File, seccompFd *os.File) error { return readSync(pipe, procSeccompDone) } -// setupUser changes the groups, gid, and uid for the user inside the container -func setupUser(config *initConfig) error { +func getExecUser(userAndGroup string) (*user.ExecUser, error) { // Set up defaults. defaultExecUser := user.ExecUser{ Uid: 0, @@ -449,26 +448,53 @@ func setupUser(config *initConfig) error { Home: "/", } - passwdPath, err := user.GetPasswdPath() - if err != nil { - return err - } + u := strings.SplitN(userAndGroup, ":", 2) - groupPath, err := user.GetGroupPath() - if err != nil { - return err + // len(u) == 1 means there is no group id, we should try to get the supplementary group IDs. + if len(u) == 1 || u[0] == "" || os.Getenv("HOME") == "" { + passwdPath, err := user.GetPasswdPath() + if err != nil { + return nil, err + } + + groupPath, err := user.GetGroupPath() + if err != nil { + return nil, err + } + + return user.GetExecUserPath(userAndGroup, &defaultExecUser, passwdPath, groupPath) + } else { + uid, err := strconv.Atoi(u[0]) + if err != nil { + return nil, err + } + gid, err := strconv.Atoi(u[1]) + if err != nil { + return nil, err + } + return &user.ExecUser{ + Uid: uid, + Gid: gid, + Home: os.Getenv("HOME"), + }, nil } +} - execUser, err := user.GetExecUserPath(config.User, &defaultExecUser, passwdPath, groupPath) +// setupUser changes the groups, gid, and uid for the user inside the container +func setupUser(config *initConfig) error { + execUser, err := getExecUser(config.User) if err != nil { return err } var addGroups []int if len(config.AdditionalGroups) > 0 { - addGroups, err = user.GetAdditionalGroupsPath(config.AdditionalGroups, groupPath) - if err != nil { - return err + for _, group := range config.AdditionalGroups { + gid, err := strconv.Atoi(group) + if err != nil { + return err + } + addGroups = append(addGroups, gid) } } diff --git a/libcontainer/integration/exec_test.go b/libcontainer/integration/exec_test.go index 9795964caf2..383408681a8 100644 --- a/libcontainer/integration/exec_test.go +++ b/libcontainer/integration/exec_test.go @@ -395,7 +395,7 @@ func TestAdditionalGroups(t *testing.T) { Env: standardEnvironment, Stdin: nil, Stdout: &stdout, - AdditionalGroups: []string{"plugdev", "audio"}, + AdditionalGroups: []string{"1", "2"}, Init: true, } err = container.Run(&pconfig) @@ -407,12 +407,12 @@ func TestAdditionalGroups(t *testing.T) { outputGroups := stdout.String() // Check that the groups output has the groups that we specified - if !strings.Contains(outputGroups, "audio") { - t.Fatalf("Listed groups do not contain the audio group as expected: %v", outputGroups) + if !strings.Contains(outputGroups, "1") { + t.Fatalf("Listed groups do not contain the group as expected: %v", outputGroups) } - if !strings.Contains(outputGroups, "plugdev") { - t.Fatalf("Listed groups do not contain the plugdev group as expected: %v", outputGroups) + if !strings.Contains(outputGroups, "2") { + t.Fatalf("Listed groups do not contain the group as expected: %v", outputGroups) } } diff --git a/libcontainer/integration/execin_test.go b/libcontainer/integration/execin_test.go index c5c324130c6..2d441a16ea3 100644 --- a/libcontainer/integration/execin_test.go +++ b/libcontainer/integration/execin_test.go @@ -162,7 +162,7 @@ func TestExecInAdditionalGroups(t *testing.T) { Env: standardEnvironment, Stdin: nil, Stdout: &stdout, - AdditionalGroups: []string{"plugdev", "audio"}, + AdditionalGroups: []string{"1", "2"}, } err = container.Run(&pconfig) ok(t, err) @@ -176,12 +176,12 @@ func TestExecInAdditionalGroups(t *testing.T) { outputGroups := stdout.String() // Check that the groups output has the groups that we specified - if !strings.Contains(outputGroups, "audio") { - t.Fatalf("Listed groups do not contain the audio group as expected: %v", outputGroups) + if !strings.Contains(outputGroups, "1") { + t.Fatalf("Listed groups do not contain the group as expected: %v", outputGroups) } - if !strings.Contains(outputGroups, "plugdev") { - t.Fatalf("Listed groups do not contain the plugdev group as expected: %v", outputGroups) + if !strings.Contains(outputGroups, "2") { + t.Fatalf("Listed groups do not contain the group as expected: %v", outputGroups) } }