Fixes #5647
Docker-DCO-1.1-Signed-off-by: Alexandr Morozov <lk4d4math@gmail.com> (github: LK4D4)
| ... | ... |
@@ -439,6 +439,8 @@ but the operator can override it: |
| 439 | 439 |
|
| 440 | 440 |
-u="": Username or UID |
| 441 | 441 |
|
| 442 |
+> **Note:** if you pass numeric uid, it must be in range 0-2147483647. |
|
| 443 |
+ |
|
| 442 | 444 |
## WORKDIR |
| 443 | 445 |
|
| 444 | 446 |
The default working directory for running binaries within a container is the |
| ... | ... |
@@ -544,6 +544,51 @@ func TestUserByID(t *testing.T) {
|
| 544 | 544 |
logDone("run - user by id")
|
| 545 | 545 |
} |
| 546 | 546 |
|
| 547 |
+func TestUserByIDBig(t *testing.T) {
|
|
| 548 |
+ cmd := exec.Command(dockerBinary, "run", "-u", "2147483648", "busybox", "id") |
|
| 549 |
+ |
|
| 550 |
+ out, _, err := runCommandWithOutput(cmd) |
|
| 551 |
+ if err == nil {
|
|
| 552 |
+ t.Fatal("No error, but must be.", out)
|
|
| 553 |
+ } |
|
| 554 |
+ if !strings.Contains(out, "Uids and gids must be in range") {
|
|
| 555 |
+ t.Fatalf("expected error about uids range, got %s", out)
|
|
| 556 |
+ } |
|
| 557 |
+ deleteAllContainers() |
|
| 558 |
+ |
|
| 559 |
+ logDone("run - user by id, id too big")
|
|
| 560 |
+} |
|
| 561 |
+ |
|
| 562 |
+func TestUserByIDNegative(t *testing.T) {
|
|
| 563 |
+ cmd := exec.Command(dockerBinary, "run", "-u", "-1", "busybox", "id") |
|
| 564 |
+ |
|
| 565 |
+ out, _, err := runCommandWithOutput(cmd) |
|
| 566 |
+ if err == nil {
|
|
| 567 |
+ t.Fatal("No error, but must be.", out)
|
|
| 568 |
+ } |
|
| 569 |
+ if !strings.Contains(out, "Uids and gids must be in range") {
|
|
| 570 |
+ t.Fatalf("expected error about uids range, got %s", out)
|
|
| 571 |
+ } |
|
| 572 |
+ deleteAllContainers() |
|
| 573 |
+ |
|
| 574 |
+ logDone("run - user by id, id negative")
|
|
| 575 |
+} |
|
| 576 |
+ |
|
| 577 |
+func TestUserByIDZero(t *testing.T) {
|
|
| 578 |
+ cmd := exec.Command(dockerBinary, "run", "-u", "0", "busybox", "id") |
|
| 579 |
+ |
|
| 580 |
+ out, _, err := runCommandWithOutput(cmd) |
|
| 581 |
+ if err != nil {
|
|
| 582 |
+ t.Fatal(err, out) |
|
| 583 |
+ } |
|
| 584 |
+ if !strings.Contains(out, "uid=0(root) gid=0(root) groups=10(wheel)") {
|
|
| 585 |
+ t.Fatalf("expected daemon user got %s", out)
|
|
| 586 |
+ } |
|
| 587 |
+ deleteAllContainers() |
|
| 588 |
+ |
|
| 589 |
+ logDone("run - user by id, zero uid")
|
|
| 590 |
+} |
|
| 591 |
+ |
|
| 547 | 592 |
func TestUserNotFound(t *testing.T) {
|
| 548 | 593 |
cmd := exec.Command(dockerBinary, "run", "-u", "notme", "busybox", "id") |
| 549 | 594 |
|
| ... | ... |
@@ -9,6 +9,15 @@ import ( |
| 9 | 9 |
"strings" |
| 10 | 10 |
) |
| 11 | 11 |
|
| 12 |
+const ( |
|
| 13 |
+ minId = 0 |
|
| 14 |
+ maxId = 1<<31 - 1 //for 32-bit systems compatibility |
|
| 15 |
+) |
|
| 16 |
+ |
|
| 17 |
+var ( |
|
| 18 |
+ ErrRange = fmt.Errorf("Uids and gids must be in range %d-%d", minId, maxId)
|
|
| 19 |
+) |
|
| 20 |
+ |
|
| 12 | 21 |
type User struct {
|
| 13 | 22 |
Name string |
| 14 | 23 |
Pass string |
| ... | ... |
@@ -194,6 +203,9 @@ func GetUserGroupSupplementary(userSpec string, defaultUid int, defaultGid int) |
| 194 | 194 |
// not numeric - we have to bail |
| 195 | 195 |
return 0, 0, nil, fmt.Errorf("Unable to find user %v", userArg)
|
| 196 | 196 |
} |
| 197 |
+ if uid < minId || uid > maxId {
|
|
| 198 |
+ return 0, 0, nil, ErrRange |
|
| 199 |
+ } |
|
| 197 | 200 |
|
| 198 | 201 |
// if userArg couldn't be found in /etc/passwd but is numeric, just roll with it - this is legit |
| 199 | 202 |
} |
| ... | ... |
@@ -226,6 +238,9 @@ func GetUserGroupSupplementary(userSpec string, defaultUid int, defaultGid int) |
| 226 | 226 |
// not numeric - we have to bail |
| 227 | 227 |
return 0, 0, nil, fmt.Errorf("Unable to find group %v", groupArg)
|
| 228 | 228 |
} |
| 229 |
+ if gid < minId || gid > maxId {
|
|
| 230 |
+ return 0, 0, nil, ErrRange |
|
| 231 |
+ } |
|
| 229 | 232 |
|
| 230 | 233 |
// if groupArg couldn't be found in /etc/group but is numeric, just roll with it - this is legit |
| 231 | 234 |
} |