Skip to content

Commit 65d54df

Browse files
committed
Support idmap mounts on volumes without userns.
Commit fda12ab ("Support idmap mounts on volumes") introduces support for idmap mount on volumes. At this time, it required userns to be used and idmap mount must have the same UID/GID mappings than userns. This commit removes this requirement, so it is possible to use idmap mount without userns. You can, of course, use id map mount with userns, but the UID/GID mappings can be different. Signed-off-by: Francis Laniel <[email protected]>
1 parent 74895d4 commit 65d54df

File tree

7 files changed

+203
-71
lines changed

7 files changed

+203
-71
lines changed

libcontainer/configs/validate/validator.go

Lines changed: 3 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ func namespaces(config *configs.Config) error {
9595
return errors.New("USER namespaces aren't enabled in the kernel")
9696
}
9797
} else {
98-
if config.UIDMappings != nil || config.GIDMappings != nil {
98+
if len(config.UIDMappings) != 0 || len(config.GIDMappings) != 0 {
9999
return errors.New("User namespace mappings specified, but USER namespace isn't enabled in the config")
100100
}
101101
}
@@ -264,14 +264,8 @@ func checkIDMapMounts(config *configs.Config, m *configs.Mount) error {
264264
if config.RootlessEUID {
265265
return fmt.Errorf("gidMappings/uidMappings is not supported when runc is being launched with EUID != 0, needs CAP_SYS_ADMIN on the runc parent's user namespace")
266266
}
267-
if len(config.UIDMappings) == 0 || len(config.GIDMappings) == 0 {
268-
return fmt.Errorf("not yet supported to use gidMappings/uidMappings in a mount without also using a user namespace")
269-
}
270-
if !sameMapping(config.UIDMappings, m.UIDMappings) {
271-
return fmt.Errorf("not yet supported for the mount uidMappings to be different than user namespace uidMapping")
272-
}
273-
if !sameMapping(config.GIDMappings, m.GIDMappings) {
274-
return fmt.Errorf("not yet supported for the mount gidMappings to be different than user namespace gidMapping")
267+
if len(m.UIDMappings) == 0 || len(m.GIDMappings) == 0 {
268+
return fmt.Errorf("id map mount without UID/GID mappings")
275269
}
276270
if !filepath.IsAbs(m.Source) {
277271
return fmt.Errorf("mount source not absolute")
@@ -298,27 +292,6 @@ func mounts(config *configs.Config) error {
298292
return nil
299293
}
300294

301-
// sameMapping checks if the mappings are the same. If the mappings are the same
302-
// but in different order, it returns false.
303-
func sameMapping(a, b []configs.IDMap) bool {
304-
if len(a) != len(b) {
305-
return false
306-
}
307-
308-
for i := range a {
309-
if a[i].ContainerID != b[i].ContainerID {
310-
return false
311-
}
312-
if a[i].HostID != b[i].HostID {
313-
return false
314-
}
315-
if a[i].Size != b[i].Size {
316-
return false
317-
}
318-
}
319-
return true
320-
}
321-
322295
func isHostNetNS(path string) (bool, error) {
323296
const currentProcessNetns = "/proc/self/ns/net"
324297

libcontainer/configs/validate/validator_test.go

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -436,8 +436,7 @@ func TestValidateIDMapMounts(t *testing.T) {
436436
},
437437
},
438438
{
439-
name: "idmap mount without userns mappings",
440-
isErr: true,
439+
name: "idmap mount without userns mappings",
441440
config: &configs.Config{
442441
Mounts: []*configs.Mount{
443442
{
@@ -451,8 +450,7 @@ func TestValidateIDMapMounts(t *testing.T) {
451450
},
452451
},
453452
{
454-
name: "idmap mounts with different userns and mount mappings",
455-
isErr: true,
453+
name: "idmap mounts with different userns and mount mappings",
456454
config: &configs.Config{
457455
UIDMappings: mapping,
458456
GIDMappings: mapping,
@@ -474,8 +472,7 @@ func TestValidateIDMapMounts(t *testing.T) {
474472
},
475473
},
476474
{
477-
name: "idmap mounts with different userns and mount mappings",
478-
isErr: true,
475+
name: "idmap mounts with different userns and mount mappings",
479476
config: &configs.Config{
480477
UIDMappings: mapping,
481478
GIDMappings: mapping,

libcontainer/container_linux.go

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -558,11 +558,6 @@ func (c *Container) shouldSendIdmapSources() bool {
558558
return false
559559
}
560560

561-
// For the time being we require userns to be in use.
562-
if !c.config.Namespaces.Contains(configs.NEWUSER) {
563-
return false
564-
}
565-
566561
// We need to send sources if there are idmap bind-mounts.
567562
for _, m := range c.config.Mounts {
568563
if m.IsBind() && m.IsIDMapped() {
@@ -2301,6 +2296,9 @@ func (c *Container) bootstrapData(cloneFlags uintptr, nsMaps map[configs.Namespa
23012296
// Idmap mount sources to open.
23022297
if it == initStandard && c.shouldSendIdmapSources() {
23032298
var mounts []byte
2299+
var uidmaps []byte
2300+
var gidmaps []byte
2301+
23042302
for _, m := range c.config.Mounts {
23052303
if m.IsBind() && m.IsIDMapped() {
23062304
// While other parts of the code check this too (like
@@ -2310,11 +2308,35 @@ func (c *Container) bootstrapData(cloneFlags uintptr, nsMaps map[configs.Namespa
23102308
return nil, fmt.Errorf("mount source string contains null byte: %q", m.Source)
23112309
}
23122310

2311+
uidBytes, err := encodeIDMapping(m.UIDMappings)
2312+
if err != nil {
2313+
return nil, err
2314+
}
2315+
gidBytes, err := encodeIDMapping(m.GIDMappings)
2316+
if err != nil {
2317+
return nil, err
2318+
}
2319+
2320+
uidmaps = append(uidmaps, uidBytes...)
2321+
gidmaps = append(gidmaps, gidBytes...)
23132322
mounts = append(mounts, []byte(m.Source)...)
23142323
}
2324+
2325+
uidmaps = append(uidmaps, byte(0))
2326+
gidmaps = append(gidmaps, byte(0))
23152327
mounts = append(mounts, byte(0))
23162328
}
23172329

2330+
r.AddData(&Bytemsg{
2331+
Type: IdmapUidmapAttr,
2332+
Value: uidmaps,
2333+
})
2334+
2335+
r.AddData(&Bytemsg{
2336+
Type: IdmapGidmapAttr,
2337+
Value: gidmaps,
2338+
})
2339+
23182340
r.AddData(&Bytemsg{
23192341
Type: IdmapSourcesAttr,
23202342
Value: mounts,

libcontainer/message_linux.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ const (
2323
GidmapPathAttr uint16 = 27289
2424
MountSourcesAttr uint16 = 27290
2525
IdmapSourcesAttr uint16 = 27291
26+
IdmapUidmapAttr uint16 = 27292
27+
IdmapGidmapAttr uint16 = 27293
2628
)
2729

2830
type Int32msg struct {

0 commit comments

Comments
 (0)