Skip to content

Commit 41b12c0

Browse files
authored
Merge pull request #913 from cloudfoundry-incubator/addgroupsnocompatible
Let the user explicitly specify `additionalGids` on `runc exec`
2 parents ec01ae5 + f9b72b1 commit 41b12c0

File tree

8 files changed

+76
-16
lines changed

8 files changed

+76
-16
lines changed

libcontainer/configs/config.go

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -148,10 +148,6 @@ type Config struct {
148148
// More information about kernel oom score calculation here: https://lwn.net/Articles/317814/
149149
OomScoreAdj int `json:"oom_score_adj"`
150150

151-
// AdditionalGroups specifies the gids that should be added to supplementary groups
152-
// in addition to those that the user belongs to.
153-
AdditionalGroups []string `json:"additional_groups"`
154-
155151
// UidMappings is an array of User ID mappings for User Namespaces
156152
UidMappings []IDMap `json:"uid_mappings"`
157153

libcontainer/container_linux.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -390,6 +390,7 @@ func (c *linuxContainer) newInitConfig(process *Process) *initConfig {
390390
Args: process.Args,
391391
Env: process.Env,
392392
User: process.User,
393+
AdditionalGroups: process.AdditionalGroups,
393394
Cwd: process.Cwd,
394395
Console: process.consolePath,
395396
Capabilities: process.Capabilities,

libcontainer/init_linux.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ type initConfig struct {
5252
AppArmorProfile string `json:"apparmor_profile"`
5353
NoNewPrivileges bool `json:"no_new_privileges"`
5454
User string `json:"user"`
55+
AdditionalGroups []string `json:"additional_groups"`
5556
Config *configs.Config `json:"config"`
5657
Console string `json:"console"`
5758
Networks []*network `json:"network"`
@@ -213,8 +214,8 @@ func setupUser(config *initConfig) error {
213214
}
214215

215216
var addGroups []int
216-
if len(config.Config.AdditionalGroups) > 0 {
217-
addGroups, err = user.GetAdditionalGroupsPath(config.Config.AdditionalGroups, groupPath)
217+
if len(config.AdditionalGroups) > 0 {
218+
addGroups, err = user.GetAdditionalGroupsPath(config.AdditionalGroups, groupPath)
218219
if err != nil {
219220
return err
220221
}

libcontainer/integration/exec_test.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -431,7 +431,6 @@ func TestAdditionalGroups(t *testing.T) {
431431
defer remove(rootfs)
432432

433433
config := newTemplateConfig(rootfs)
434-
config.AdditionalGroups = []string{"plugdev", "audio"}
435434

436435
factory, err := libcontainer.New(root, libcontainer.Cgroupfs)
437436
ok(t, err)
@@ -442,11 +441,12 @@ func TestAdditionalGroups(t *testing.T) {
442441

443442
var stdout bytes.Buffer
444443
pconfig := libcontainer.Process{
445-
Cwd: "/",
446-
Args: []string{"sh", "-c", "id", "-Gn"},
447-
Env: standardEnvironment,
448-
Stdin: nil,
449-
Stdout: &stdout,
444+
Cwd: "/",
445+
Args: []string{"sh", "-c", "id", "-Gn"},
446+
Env: standardEnvironment,
447+
Stdin: nil,
448+
Stdout: &stdout,
449+
AdditionalGroups: []string{"plugdev", "audio"},
450450
}
451451
err = container.Run(&pconfig)
452452
ok(t, err)

libcontainer/integration/execin_test.go

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,64 @@ func testExecInRlimit(t *testing.T, userns bool) {
134134
}
135135
}
136136

137+
func TestExecInAdditionalGroups(t *testing.T) {
138+
if testing.Short() {
139+
return
140+
}
141+
142+
rootfs, err := newRootfs()
143+
ok(t, err)
144+
defer remove(rootfs)
145+
146+
config := newTemplateConfig(rootfs)
147+
container, err := newContainer(config)
148+
ok(t, err)
149+
defer container.Destroy()
150+
151+
// Execute a first process in the container
152+
stdinR, stdinW, err := os.Pipe()
153+
ok(t, err)
154+
process := &libcontainer.Process{
155+
Cwd: "/",
156+
Args: []string{"cat"},
157+
Env: standardEnvironment,
158+
Stdin: stdinR,
159+
}
160+
err = container.Run(process)
161+
stdinR.Close()
162+
defer stdinW.Close()
163+
ok(t, err)
164+
165+
var stdout bytes.Buffer
166+
pconfig := libcontainer.Process{
167+
Cwd: "/",
168+
Args: []string{"sh", "-c", "id", "-Gn"},
169+
Env: standardEnvironment,
170+
Stdin: nil,
171+
Stdout: &stdout,
172+
AdditionalGroups: []string{"plugdev", "audio"},
173+
}
174+
err = container.Run(&pconfig)
175+
ok(t, err)
176+
177+
// Wait for process
178+
waitProcess(&pconfig, t)
179+
180+
stdinW.Close()
181+
waitProcess(process, t)
182+
183+
outputGroups := string(stdout.Bytes())
184+
185+
// Check that the groups output has the groups that we specified
186+
if !strings.Contains(outputGroups, "audio") {
187+
t.Fatalf("Listed groups do not contain the audio group as expected: %v", outputGroups)
188+
}
189+
190+
if !strings.Contains(outputGroups, "plugdev") {
191+
t.Fatalf("Listed groups do not contain the plugdev group as expected: %v", outputGroups)
192+
}
193+
}
194+
137195
func TestExecInError(t *testing.T) {
138196
if testing.Short() {
139197
return

libcontainer/process.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@ type Process struct {
2828
// local to the container's user and group configuration.
2929
User string
3030

31+
// AdditionalGroups specifies the gids that should be added to supplementary groups
32+
// in addition to those that the user belongs to.
33+
AdditionalGroups []string
34+
3135
// Cwd will change the processes current working directory inside the container's rootfs.
3236
Cwd string
3337

libcontainer/specconv/spec_linux.go

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import (
88
"fmt"
99
"os"
1010
"path/filepath"
11-
"strconv"
1211
"strings"
1312
"syscall"
1413
"time"
@@ -229,9 +228,6 @@ func CreateLibcontainerConfig(opts *CreateOpts) (*configs.Config, error) {
229228
if spec.Linux.Resources != nil && spec.Linux.Resources.OOMScoreAdj != nil {
230229
config.OomScoreAdj = *spec.Linux.Resources.OOMScoreAdj
231230
}
232-
for _, g := range spec.Process.User.AdditionalGids {
233-
config.AdditionalGroups = append(config.AdditionalGroups, strconv.FormatUint(uint64(g), 10))
234-
}
235231
createHooks(spec, config)
236232
config.MountLabel = spec.Linux.MountLabel
237233
config.Version = specs.Version

utils_linux.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"fmt"
88
"os"
99
"path/filepath"
10+
"strconv"
1011
"syscall"
1112

1213
"github.com/Sirupsen/logrus"
@@ -83,6 +84,9 @@ func newProcess(p specs.Process) (*libcontainer.Process, error) {
8384
NoNewPrivileges: &p.NoNewPrivileges,
8485
AppArmorProfile: p.ApparmorProfile,
8586
}
87+
for _, gid := range p.User.AdditionalGids {
88+
lp.AdditionalGroups = append(lp.AdditionalGroups, strconv.FormatUint(uint64(gid), 10))
89+
}
8690
for _, rlimit := range p.Rlimits {
8791
rl, err := createLibContainerRlimit(rlimit)
8892
if err != nil {

0 commit comments

Comments
 (0)