Skip to content
This repository was archived by the owner on Aug 14, 2020. It is now read-only.
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 9aa8eda

Browse files
committedJun 15, 2016
actool: add support for patching seccomp isolators
1 parent ea84f7f commit 9aa8eda

File tree

1 file changed

+80
-4
lines changed

1 file changed

+80
-4
lines changed
 

‎actool/manifest.go

+80-4
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ var (
5151
patchMounts string
5252
patchPorts string
5353
patchIsolators string
54+
patchSeccompMode string
55+
patchSeccompSet string
5456

5557
catPrettyPrint bool
5658

@@ -69,6 +71,8 @@ var (
6971
[--ports=query,protocol=tcp,port=8080[:query2,...]]
7072
[--supplementary-groups=gid1,gid2,...]
7173
[--isolators=resource/cpu,request=50m,limit=100m[:resource/memory,...]]
74+
[--seccomp-mode=remove|retain[,errno=EPERM]]
75+
[--seccomp-set=syscall1,syscall2,...]]
7276
[--replace]
7377
INPUT_ACI_FILE
7478
[OUTPUT_ACI_FILE]`,
@@ -99,6 +103,8 @@ func init() {
99103
cmdPatchManifest.Flags.StringVar(&patchMounts, "mounts", "", "Replace mount points")
100104
cmdPatchManifest.Flags.StringVar(&patchPorts, "ports", "", "Replace ports")
101105
cmdPatchManifest.Flags.StringVar(&patchIsolators, "isolators", "", "Replace isolators")
106+
cmdPatchManifest.Flags.StringVar(&patchSeccompMode, "seccomp-mode", "", "Enable and configure seccomp isolator")
107+
cmdPatchManifest.Flags.StringVar(&patchSeccompSet, "seccomp-set", "", "Set of syscalls for seccomp isolator enforcing")
102108

103109
cmdCatManifest.Flags.BoolVar(&catPrettyPrint, "pretty-print", false, "Print with better style")
104110
}
@@ -211,7 +217,11 @@ func patchManifest(im *schema.ImageManifest) error {
211217
if err != nil {
212218
return fmt.Errorf("cannot parse capability %q: %v", patchCaps, err)
213219
}
214-
app.Isolators = append(app.Isolators, caps.AsIsolator())
220+
isolator, err = caps.AsIsolator()
221+
if err != nil {
222+
return err
223+
}
224+
app.Isolators = append(app.Isolators, *isolator)
215225
}
216226
if patchRevokeCaps != "" {
217227
isolator := app.Isolators.GetByName(types.LinuxCapabilitiesRevokeSetName)
@@ -225,7 +235,11 @@ func patchManifest(im *schema.ImageManifest) error {
225235
if err != nil {
226236
return fmt.Errorf("cannot parse capability %q: %v", patchRevokeCaps, err)
227237
}
228-
app.Isolators = append(app.Isolators, caps.AsIsolator())
238+
isolator, err = caps.AsIsolator()
239+
if err != nil {
240+
return err
241+
}
242+
app.Isolators = append(app.Isolators, *isolator)
229243
}
230244

231245
if patchMounts != "" {
@@ -250,6 +264,25 @@ func patchManifest(im *schema.ImageManifest) error {
250264
}
251265
}
252266

267+
// Parse seccomp args and override existing seccomp isolators
268+
if patchSeccompMode != "" {
269+
seccomp, err := parseSeccompArgs(patchSeccompMode, patchSeccompSet)
270+
if err != nil {
271+
return err
272+
}
273+
seccompIsolator, err := seccomp.AsIsolator()
274+
if err != nil {
275+
return err
276+
}
277+
seccompReps := []types.ACIdentifier{types.LinuxSeccompRemoveSetName, types.LinuxSeccompRetainSetName}
278+
_, err = app.Isolators.ReplaceIsolatorsByName(*seccompIsolator, seccompReps)
279+
if err != nil {
280+
return err
281+
}
282+
} else if patchSeccompSet != "" {
283+
return fmt.Errorf("--seccomp-set specified without --seccomp-mode")
284+
}
285+
253286
if patchIsolators != "" {
254287
isolators := strings.Split(patchIsolators, ":")
255288
for _, is := range isolators {
@@ -260,14 +293,16 @@ func patchManifest(im *schema.ImageManifest) error {
260293

261294
_, ok := types.ResourceIsolatorNames[name]
262295

263-
if name == types.LinuxNoNewPrivilegesName {
296+
switch name {
297+
case types.LinuxNoNewPrivilegesName:
264298
ok = true
265299
kv := strings.Split(is, ",")
266300
if len(kv) != 2 {
267301
return fmt.Errorf("isolator %s: invalid format", name)
268302
}
269-
270303
isolatorStr = fmt.Sprintf(`{ "name": "%s", "value": %s }`, name, kv[1])
304+
case types.LinuxSeccompRemoveSetName, types.LinuxSeccompRetainSetName:
305+
ok = false
271306
}
272307

273308
if !ok {
@@ -284,6 +319,47 @@ func patchManifest(im *schema.ImageManifest) error {
284319
return nil
285320
}
286321

322+
// parseSeccompArgs parses seccomp mode and set CLI flags, preparing an
323+
// appropriate seccomp isolator.
324+
func parseSeccompArgs(patchSeccompMode string, patchSeccompSet string) (types.AsIsolator, error) {
325+
// Parse mode flag and additional keyed arguments.
326+
var errno, mode string
327+
args := strings.Split(patchSeccompMode, ",")
328+
for _, a := range args {
329+
kv := strings.Split(a, "=")
330+
switch len(kv) {
331+
case 1:
332+
// mode, either "remove" or "retain"
333+
mode = kv[0]
334+
case 2:
335+
// k=v argument, only "errno" allowed for now
336+
if kv[0] == "errno" {
337+
errno = kv[1]
338+
} else {
339+
return nil, fmt.Errorf("invalid seccomp-mode optional argument: %s", a)
340+
}
341+
default:
342+
return nil, fmt.Errorf("cannot parse seccomp-mode argument: %s", a)
343+
}
344+
}
345+
346+
// Instantiate an Isolator with the content specified by the --seccomp-set parameter.
347+
var err error
348+
var seccomp types.AsIsolator
349+
switch mode {
350+
case "remove":
351+
seccomp, err = types.NewLinuxSeccompRemoveSet(errno, strings.Split(patchSeccompSet, ",")...)
352+
case "retain":
353+
seccomp, err = types.NewLinuxSeccompRetainSet(errno, strings.Split(patchSeccompSet, ",")...)
354+
default:
355+
err = fmt.Errorf("unknown seccomp mode %s", mode)
356+
}
357+
if err != nil {
358+
return nil, fmt.Errorf("cannot parse seccomp isolator: %s", err)
359+
}
360+
return seccomp, nil
361+
}
362+
287363
// extractManifest iterates over the tar reader and locate the manifest. Once
288364
// located, the manifest can be printed, replaced or patched.
289365
func extractManifest(tr *tar.Reader, tw *tar.Writer, printManifest bool, newManifest []byte) error {

0 commit comments

Comments
 (0)
This repository has been archived.