...
1 package validate
2
3 import (
4 "errors"
5 "fmt"
6 "strings"
7
8 "github.com/opencontainers/runc/libcontainer/configs"
9 )
10
11
12
13 func (v *ConfigValidator) rootlessEUID(config *configs.Config) error {
14 if !config.RootlessEUID {
15 return nil
16 }
17 if err := rootlessEUIDMappings(config); err != nil {
18 return err
19 }
20 if err := rootlessEUIDMount(config); err != nil {
21 return err
22 }
23
24
25
26
27
28 return nil
29 }
30
31 func rootlessEUIDMappings(config *configs.Config) error {
32 if !config.Namespaces.Contains(configs.NEWUSER) {
33 return errors.New("rootless container requires user namespaces")
34 }
35
36 if path := config.Namespaces.PathOf(configs.NEWUSER); path == "" {
37 if len(config.UidMappings) == 0 {
38 return errors.New("rootless containers requires at least one UID mapping")
39 }
40 if len(config.GidMappings) == 0 {
41 return errors.New("rootless containers requires at least one GID mapping")
42 }
43 }
44 return nil
45 }
46
47
48
49
50 func rootlessEUIDMount(config *configs.Config) error {
51
52
53
54
55 for _, mount := range config.Mounts {
56
57
58 for _, opt := range strings.Split(mount.Data, ",") {
59 if strings.HasPrefix(opt, "uid=") {
60 var uid int
61 n, err := fmt.Sscanf(opt, "uid=%d", &uid)
62 if n != 1 || err != nil {
63
64 continue
65 }
66 if _, err := config.HostUID(uid); err != nil {
67 return fmt.Errorf("cannot specify uid=%d mount option for rootless container: %w", uid, err)
68 }
69 }
70
71 if strings.HasPrefix(opt, "gid=") {
72 var gid int
73 n, err := fmt.Sscanf(opt, "gid=%d", &gid)
74 if n != 1 || err != nil {
75
76 continue
77 }
78 if _, err := config.HostGID(gid); err != nil {
79 return fmt.Errorf("cannot specify gid=%d mount option for rootless container: %w", gid, err)
80 }
81 }
82 }
83 }
84
85 return nil
86 }
87
View as plain text