|
9 | 9 |
|
10 | 10 | rspec "github.com/opencontainers/runtime-spec/specs-go" |
11 | 11 | "github.com/opencontainers/runtime-tools/generate" |
| 12 | + "github.com/opencontainers/runtime-tools/generate/seccomp" |
12 | 13 | "github.com/urfave/cli" |
13 | 14 | ) |
14 | 15 |
|
@@ -60,11 +61,17 @@ var generateFlags = []cli.Flag{ |
60 | 61 | cli.BoolFlag{Name: "read-only", Usage: "make the container's rootfs read-only"}, |
61 | 62 | cli.StringFlag{Name: "root-propagation", Usage: "mount propagation for root"}, |
62 | 63 | cli.StringFlag{Name: "rootfs", Value: "rootfs", Usage: "path to the rootfs"}, |
63 | | - cli.StringSliceFlag{Name: "seccomp-arch", Usage: "specifies Additional architectures permitted to be used for system calls"}, |
64 | | - cli.StringSliceFlag{Name: "seccomp-allow", Usage: "specifies syscalls to be added to allowed"}, |
65 | | - cli.StringFlag{Name: "seccomp-default", Usage: "specifies the the defaultaction of Seccomp syscall restrictions"}, |
66 | | - cli.StringSliceFlag{Name: "seccomp-errno", Usage: "specifies syscalls to be added to list that returns an error"}, |
67 | | - cli.StringSliceFlag{Name: "seccomp-syscalls", Usage: "specifies Additional architectures permitted to be used for system calls, e.g Name:Action:Arg1_index/Arg1_value/Arg1_valuetwo/Arg1_op, Arg2_index/Arg2_value/Arg2_valuetwo/Arg2_op "}, |
| 64 | + cli.StringFlag{Name: "seccomp-allow", Usage: "specifies syscalls to respond with allow"}, |
| 65 | + cli.StringFlag{Name: "seccomp-arch", Usage: "specifies additional architectures permitted to be used for system calls"}, |
| 66 | + cli.StringFlag{Name: "seccomp-default", Usage: "specifies default action to be used for system calls and removes existing rules with specified action"}, |
| 67 | + cli.StringFlag{Name: "seccomp-default-force", Usage: "same as seccomp-default but does not remove existing rules with specified action"}, |
| 68 | + cli.StringFlag{Name: "seccomp-errno", Usage: "specifies syscalls to respond with errno"}, |
| 69 | + cli.StringFlag{Name: "seccomp-kill", Usage: "specifies syscalls to respond with kill"}, |
| 70 | + cli.BoolFlag{Name: "seccomp-only", Usage: "specifies to export just a seccomp configuration file"}, |
| 71 | + cli.StringFlag{Name: "seccomp-remove", Usage: "specifies syscalls to remove seccomp rules for"}, |
| 72 | + cli.BoolFlag{Name: "seccomp-remove-all", Usage: "removes all syscall rules from seccomp configuration"}, |
| 73 | + cli.StringFlag{Name: "seccomp-trace", Usage: "specifies syscalls to respond with trace"}, |
| 74 | + cli.StringFlag{Name: "seccomp-trap", Usage: "specifies syscalls to respond with trap"}, |
68 | 75 | cli.StringFlag{Name: "selinux-label", Usage: "process selinux label"}, |
69 | 76 | cli.StringSliceFlag{Name: "sysctl", Usage: "add sysctl settings e.g net.ipv4.forward=1"}, |
70 | 77 | cli.StringFlag{Name: "template", Usage: "base template to use for creating the configuration"}, |
@@ -102,11 +109,13 @@ var generateCommand = cli.Command{ |
102 | 109 | return err |
103 | 110 | } |
104 | 111 |
|
| 112 | + var exportOpts generate.ExportOptions |
| 113 | + exportOpts.Seccomp = context.Bool("seccomp-only") |
| 114 | + |
105 | 115 | if context.IsSet("output") { |
106 | | - output := context.String("output") |
107 | | - err = specgen.SaveToFile(output) |
| 116 | + err = specgen.SaveToFile(context.String("output"), exportOpts) |
108 | 117 | } else { |
109 | | - err = specgen.Save(os.Stdout) |
| 118 | + err = specgen.Save(os.Stdout, exportOpts) |
110 | 119 | } |
111 | 120 | if err != nil { |
112 | 121 | return err |
@@ -395,69 +404,8 @@ func setupSpec(g *generate.Generator, context *cli.Context) error { |
395 | 404 | g.SetLinuxResourcesMemorySwappiness(context.Uint64("linux-mem-swappiness")) |
396 | 405 | } |
397 | 406 |
|
398 | | - if context.IsSet("linux-pids-limit") { |
399 | | - g.SetLinuxResourcesPidsLimit(context.Int64("linux-pids-limit")) |
400 | | - } |
401 | | - |
402 | | - var sd string |
403 | | - var sa, ss []string |
404 | | - |
405 | | - if context.IsSet("seccomp-default") { |
406 | | - sd = context.String("seccomp-default") |
407 | | - } |
408 | | - |
409 | | - if context.IsSet("seccomp-arch") { |
410 | | - sa = context.StringSlice("seccomp-arch") |
411 | | - } |
412 | | - |
413 | | - if context.IsSet("seccomp-syscalls") { |
414 | | - ss = context.StringSlice("seccomp-syscalls") |
415 | | - } |
416 | | - |
417 | | - if sd == "" && len(sa) == 0 && len(ss) == 0 { |
418 | | - return nil |
419 | | - } |
420 | | - |
421 | | - // Set the DefaultAction of seccomp |
422 | | - if context.IsSet("seccomp-default") { |
423 | | - if err := g.SetLinuxSeccompDefault(sd); err != nil { |
424 | | - return err |
425 | | - } |
426 | | - } |
427 | | - |
428 | | - // Add the additional architectures permitted to be used for system calls |
429 | | - if context.IsSet("seccomp-arch") { |
430 | | - for _, arch := range sa { |
431 | | - if err := g.AddLinuxSeccompArch(arch); err != nil { |
432 | | - return err |
433 | | - } |
434 | | - } |
435 | | - } |
436 | | - |
437 | | - // Set syscall restrict in Seccomp |
438 | | - if context.IsSet("seccomp-syscalls") { |
439 | | - for _, syscall := range ss { |
440 | | - if err := g.AddLinuxSeccompSyscall(syscall); err != nil { |
441 | | - return err |
442 | | - } |
443 | | - } |
444 | | - } |
445 | | - |
446 | | - if context.IsSet("seccomp-allow") { |
447 | | - seccompAllows := context.StringSlice("seccomp-allow") |
448 | | - for _, s := range seccompAllows { |
449 | | - g.AddLinuxSeccompSyscallAllow(s) |
450 | | - } |
451 | | - } |
452 | | - |
453 | | - if context.IsSet("seccomp-errno") { |
454 | | - seccompErrnos := context.StringSlice("seccomp-errno") |
455 | | - for _, s := range seccompErrnos { |
456 | | - g.AddLinuxSeccompSyscallErrno(s) |
457 | | - } |
458 | | - } |
459 | | - |
460 | | - return nil |
| 407 | + err := addSeccomp(context, g) |
| 408 | + return err |
461 | 409 | } |
462 | 410 |
|
463 | 411 | func setupLinuxNamespaces(context *cli.Context, g *generate.Generator, needsNewUser bool) { |
@@ -543,3 +491,120 @@ func parseBindMount(s string) (string, string, string, error) { |
543 | 491 |
|
544 | 492 | return source, dest, options, nil |
545 | 493 | } |
| 494 | + |
| 495 | +func addSeccomp(context *cli.Context, g *generate.Generator) error { |
| 496 | + |
| 497 | + // Set the DefaultAction of seccomp |
| 498 | + if context.IsSet("seccomp-default") { |
| 499 | + seccompDefault := context.String("seccomp-default") |
| 500 | + err := g.SetDefaultSeccompAction(seccompDefault) |
| 501 | + if err != nil { |
| 502 | + return err |
| 503 | + } |
| 504 | + } else if context.IsSet("seccomp-default-force") { |
| 505 | + seccompDefaultForced := context.String("seccomp-default-force") |
| 506 | + err := g.SetDefaultSeccompActionForce(seccompDefaultForced) |
| 507 | + if err != nil { |
| 508 | + return err |
| 509 | + } |
| 510 | + } |
| 511 | + |
| 512 | + // Add the additional architectures permitted to be used for system calls |
| 513 | + if context.IsSet("seccomp-arch") { |
| 514 | + seccompArch := context.String("seccomp-arch") |
| 515 | + architectureArgs := strings.Split(seccompArch, ",") |
| 516 | + for _, arg := range architectureArgs { |
| 517 | + err := g.SetSeccompArchitecture(arg) |
| 518 | + if err != nil { |
| 519 | + return err |
| 520 | + } |
| 521 | + } |
| 522 | + } |
| 523 | + |
| 524 | + if context.IsSet("seccomp-errno") { |
| 525 | + err := seccompSet(context, "errno", g) |
| 526 | + if err != nil { |
| 527 | + return err |
| 528 | + } |
| 529 | + } |
| 530 | + |
| 531 | + if context.IsSet("seccomp-kill") { |
| 532 | + err := seccompSet(context, "kill", g) |
| 533 | + if err != nil { |
| 534 | + return err |
| 535 | + } |
| 536 | + } |
| 537 | + |
| 538 | + if context.IsSet("seccomp-trace") { |
| 539 | + err := seccompSet(context, "trace", g) |
| 540 | + if err != nil { |
| 541 | + return err |
| 542 | + } |
| 543 | + } |
| 544 | + |
| 545 | + if context.IsSet("seccomp-trap") { |
| 546 | + err := seccompSet(context, "trap", g) |
| 547 | + if err != nil { |
| 548 | + return err |
| 549 | + } |
| 550 | + } |
| 551 | + |
| 552 | + if context.IsSet("seccomp-allow") { |
| 553 | + err := seccompSet(context, "allow", g) |
| 554 | + if err != nil { |
| 555 | + return err |
| 556 | + } |
| 557 | + } |
| 558 | + |
| 559 | + if context.IsSet("seccomp-remove") { |
| 560 | + seccompRemove := context.String("seccomp-remove") |
| 561 | + err := g.RemoveSeccompRule(seccompRemove) |
| 562 | + if err != nil { |
| 563 | + return err |
| 564 | + } |
| 565 | + } |
| 566 | + |
| 567 | + if context.IsSet("seccomp-remove-all") { |
| 568 | + err := g.RemoveAllSeccompRules() |
| 569 | + if err != nil { |
| 570 | + return err |
| 571 | + } |
| 572 | + } |
| 573 | + return nil |
| 574 | +} |
| 575 | + |
| 576 | +func seccompSet(context *cli.Context, seccompFlag string, g *generate.Generator) error { |
| 577 | + flagInput := context.String("seccomp-" + seccompFlag) |
| 578 | + flagArgs := strings.Split(flagInput, ",") |
| 579 | + setSyscallArgsSlice := []seccomp.SyscallOpts{} |
| 580 | + for _, flagArg := range flagArgs { |
| 581 | + comparisonArgs := strings.Split(flagArg, ":") |
| 582 | + if len(comparisonArgs) == 5 { |
| 583 | + setSyscallArgs := seccomp.SyscallOpts{ |
| 584 | + Action: seccompFlag, |
| 585 | + Syscall: comparisonArgs[0], |
| 586 | + Index: comparisonArgs[1], |
| 587 | + Value: comparisonArgs[2], |
| 588 | + ValueTwo: comparisonArgs[3], |
| 589 | + Operator: comparisonArgs[4], |
| 590 | + } |
| 591 | + setSyscallArgsSlice = append(setSyscallArgsSlice, setSyscallArgs) |
| 592 | + } else if len(comparisonArgs) == 1 { |
| 593 | + setSyscallArgs := seccomp.SyscallOpts{ |
| 594 | + Action: seccompFlag, |
| 595 | + Syscall: comparisonArgs[0], |
| 596 | + } |
| 597 | + setSyscallArgsSlice = append(setSyscallArgsSlice, setSyscallArgs) |
| 598 | + } else { |
| 599 | + return fmt.Errorf("invalid syscall argument formatting %v", comparisonArgs) |
| 600 | + } |
| 601 | + |
| 602 | + for _, r := range setSyscallArgsSlice { |
| 603 | + err := g.SetSyscallAction(r) |
| 604 | + if err != nil { |
| 605 | + return err |
| 606 | + } |
| 607 | + } |
| 608 | + } |
| 609 | + return nil |
| 610 | +} |
0 commit comments