Stop sorting uid and gid ranges in id maps

Moby currently sorts uid and gid ranges in id maps. This causes subuid
and subgid files to be interpreted wrongly.

The subuid file

```
> cat /etc/subuid
jonas:100000:1000
jonas:1000:1
```

configures that the container uids 0-999 are mapped to the host uids
100000-100999 and uid 1000 in the container is mapped to uid 1000 on the
host. The expected uid_map is:

```
> docker run ubuntu cat /proc/self/uid_map
         0     100000       1000
      1000       1000          1
```

Moby currently sorts the ranges by the first id in the range. Therefore
with the subuid file above the uid 0 in the container is mapped to uid
100000 on host and the uids 1-1000 in container are mapped to the uids
1-1000 on the host. The resulting uid_map is:

```
> docker run ubuntu cat /proc/self/uid_map
         0       1000          1
         1     100000       1000
```

The ordering was implemented to work around a limitation in Linux 3.8.
This is fixed since Linux 3.9 as stated on the user namespaces manpage
[1]:

> In the initial implementation (Linux 3.8), this requirement was
> satisfied by a simplistic implementation that imposed the further
> requirement that the values in both field 1 and field 2 of successive
> lines must be in ascending numerical order, which prevented some
> otherwise valid maps from being created.  Linux 3.9 and later fix this
> limitation, allowing any valid set of nonoverlapping maps.

This fix changes the interpretation of subuid and subgid files which do
not have the ids of in the numerical order for each individual user.
This breaks users that rely on the current behaviour.

The desired mapping above - map low user ids in the container to high
user ids on the host and some higher user ids in the container to lower
user on host - can unfortunately not archived with the current
behaviour.

[1] http://man7.org/linux/man-pages/man7/user_namespaces.7.html

Signed-off-by: Jonas Dohse <jonas@dohse.ch>
This commit is contained in:
Jonas Dohse 2019-05-30 16:11:22 +02:00
parent 8d760280a2
commit c4628d79d2
2 changed files with 28 additions and 3 deletions

View File

@ -4,7 +4,6 @@ import (
"bufio"
"fmt"
"os"
"sort"
"strconv"
"strings"
)
@ -203,8 +202,6 @@ func (i *IdentityMapping) GIDs() []IDMap {
func createIDMap(subidRanges ranges) []IDMap {
idMap := []IDMap{}
// sort the ranges by lowest ID first
sort.Sort(subidRanges)
containerID := 0
for _, idrange := range subidRanges {
idMap = append(idMap, IDMap{

View File

@ -0,0 +1,28 @@
package idtools // import "github.com/docker/docker/pkg/idtools"
import (
"testing"
"gotest.tools/assert"
)
func TestCreateIDMapOrder(t *testing.T) {
subidRanges := ranges{
{100000, 1000},
{1000, 1},
}
idMap := createIDMap(subidRanges)
assert.DeepEqual(t, idMap, []IDMap{
{
ContainerID: 0,
HostID: 100000,
Size: 1000,
},
{
ContainerID: 1000,
HostID: 1000,
Size: 1,
},
})
}