github.com/containers/libpod@v1.9.4-0.20220419124438-4284fd425507/pkg/specgen/security.go (about) 1 package specgen 2 3 // ToCreateOptions convert the SecurityConfig to a slice of container create 4 // options. 5 /* 6 func (c *SecurityConfig) ToCreateOptions() ([]libpod.CtrCreateOption, error) { 7 options := make([]libpod.CtrCreateOption, 0) 8 options = append(options, libpod.WithSecLabels(c.LabelOpts)) 9 options = append(options, libpod.WithPrivileged(c.Privileged)) 10 return options, nil 11 } 12 */ 13 14 // SetLabelOpts sets the label options of the SecurityConfig according to the 15 // input. 16 /* 17 func (c *SecurityConfig) SetLabelOpts(runtime *libpod.Runtime, pidConfig *PidConfig, ipcConfig *IpcConfig) error { 18 if c.Privileged { 19 c.LabelOpts = label.DisableSecOpt() 20 return nil 21 } 22 23 var labelOpts []string 24 if pidConfig.PidMode.IsHost() { 25 labelOpts = append(labelOpts, label.DisableSecOpt()...) 26 } else if pidConfig.PidMode.IsContainer() { 27 ctr, err := runtime.LookupContainer(pidConfig.PidMode.Container()) 28 if err != nil { 29 return errors.Wrapf(err, "container %q not found", pidConfig.PidMode.Container()) 30 } 31 secopts, err := label.DupSecOpt(ctr.ProcessLabel()) 32 if err != nil { 33 return errors.Wrapf(err, "failed to duplicate label %q ", ctr.ProcessLabel()) 34 } 35 labelOpts = append(labelOpts, secopts...) 36 } 37 38 if ipcConfig.IpcMode.IsHost() { 39 labelOpts = append(labelOpts, label.DisableSecOpt()...) 40 } else if ipcConfig.IpcMode.IsContainer() { 41 ctr, err := runtime.LookupContainer(ipcConfig.IpcMode.Container()) 42 if err != nil { 43 return errors.Wrapf(err, "container %q not found", ipcConfig.IpcMode.Container()) 44 } 45 secopts, err := label.DupSecOpt(ctr.ProcessLabel()) 46 if err != nil { 47 return errors.Wrapf(err, "failed to duplicate label %q ", ctr.ProcessLabel()) 48 } 49 labelOpts = append(labelOpts, secopts...) 50 } 51 52 c.LabelOpts = append(c.LabelOpts, labelOpts...) 53 return nil 54 } 55 */ 56 57 // SetSecurityOpts the the security options (labels, apparmor, seccomp, etc.). 58 func SetSecurityOpts(securityOpts []string) error { 59 return nil 60 } 61 62 // ConfigureGenerator configures the generator according to the input. 63 /* 64 func (c *SecurityConfig) ConfigureGenerator(g *generate.Generator, user *UserConfig) error { 65 // HANDLE CAPABILITIES 66 // NOTE: Must happen before SECCOMP 67 if c.Privileged { 68 g.SetupPrivileged(true) 69 } 70 71 useNotRoot := func(user string) bool { 72 if user == "" || user == "root" || user == "0" { 73 return false 74 } 75 return true 76 } 77 78 configSpec := g.Config 79 var err error 80 var defaultCaplist []string 81 bounding := configSpec.Process.Capabilities.Bounding 82 if useNotRoot(user.User) { 83 configSpec.Process.Capabilities.Bounding = defaultCaplist 84 } 85 defaultCaplist, err = capabilities.MergeCapabilities(configSpec.Process.Capabilities.Bounding, c.CapAdd, c.CapDrop) 86 if err != nil { 87 return err 88 } 89 90 privCapRequired := []string{} 91 92 if !c.Privileged && len(c.CapRequired) > 0 { 93 // Pass CapRequired in CapAdd field to normalize capabilities names 94 capRequired, err := capabilities.MergeCapabilities(nil, c.CapRequired, nil) 95 if err != nil { 96 logrus.Errorf("capabilities requested by user or image are not valid: %q", strings.Join(c.CapRequired, ",")) 97 } else { 98 // Verify all capRequiered are in the defaultCapList 99 for _, cap := range capRequired { 100 if !util.StringInSlice(cap, defaultCaplist) { 101 privCapRequired = append(privCapRequired, cap) 102 } 103 } 104 } 105 if len(privCapRequired) == 0 { 106 defaultCaplist = capRequired 107 } else { 108 logrus.Errorf("capabilities requested by user or image are not allowed by default: %q", strings.Join(privCapRequired, ",")) 109 } 110 } 111 configSpec.Process.Capabilities.Bounding = defaultCaplist 112 configSpec.Process.Capabilities.Permitted = defaultCaplist 113 configSpec.Process.Capabilities.Inheritable = defaultCaplist 114 configSpec.Process.Capabilities.Effective = defaultCaplist 115 configSpec.Process.Capabilities.Ambient = defaultCaplist 116 if useNotRoot(user.User) { 117 defaultCaplist, err = capabilities.MergeCapabilities(bounding, c.CapAdd, c.CapDrop) 118 if err != nil { 119 return err 120 } 121 } 122 configSpec.Process.Capabilities.Bounding = defaultCaplist 123 124 // HANDLE SECCOMP 125 if c.SeccompProfilePath != "unconfined" { 126 seccompConfig, err := getSeccompConfig(c, configSpec) 127 if err != nil { 128 return err 129 } 130 configSpec.Linux.Seccomp = seccompConfig 131 } 132 133 // Clear default Seccomp profile from Generator for privileged containers 134 if c.SeccompProfilePath == "unconfined" || c.Privileged { 135 configSpec.Linux.Seccomp = nil 136 } 137 138 for _, opt := range c.SecurityOpts { 139 // Split on both : and = 140 splitOpt := strings.Split(opt, "=") 141 if len(splitOpt) == 1 { 142 splitOpt = strings.Split(opt, ":") 143 } 144 if len(splitOpt) < 2 { 145 continue 146 } 147 switch splitOpt[0] { 148 case "label": 149 configSpec.Annotations[libpod.InspectAnnotationLabel] = splitOpt[1] 150 case "seccomp": 151 configSpec.Annotations[libpod.InspectAnnotationSeccomp] = splitOpt[1] 152 case "apparmor": 153 configSpec.Annotations[libpod.InspectAnnotationApparmor] = splitOpt[1] 154 } 155 } 156 157 g.SetRootReadonly(c.ReadOnlyRootfs) 158 for sysctlKey, sysctlVal := range c.Sysctl { 159 g.AddLinuxSysctl(sysctlKey, sysctlVal) 160 } 161 162 return nil 163 } 164 165 */