Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

seccomp: add support for flags #3390

Merged
merged 2 commits into from
Jul 29, 2022
Merged

Conversation

alban
Copy link
Contributor

@alban alban commented Feb 22, 2022

List of seccomp flags defined in runtime-spec:

  • SECCOMP_FILTER_FLAG_TSYNC
  • SECCOMP_FILTER_FLAG_LOG
  • SECCOMP_FILTER_FLAG_SPEC_ALLOW

Note that runc does not apply SECCOMP_FILTER_FLAG_TSYNC. It does not
make sense to apply the seccomp filter on only one thread; other threads
will be terminated after exec anyway.

See similar commit in crun:
containers/crun@fefabff

Note that SECCOMP_FILTER_FLAG_WAIT_KILLABLE_RECV (introduced by
https://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git/commit/?id=c2aa2dfef243
in Linux 5.19-rc1) is not added yet because Linux 5.19 is not released
yet.


Tests:

$ make localintegration
...
ok 103 runc run [seccomp] (SECCOMP_FILTER_FLAG_*)

cc @rata @saschagrunert

rata
rata previously approved these changes Feb 22, 2022
Copy link
Member

@rata rata left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm no maintainer here, but this LGTM. Just a minor comment on the integration test

tests/integration/seccomp.bats Outdated Show resolved Hide resolved
Copy link
Contributor

@kolyshkin kolyshkin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't add support for SECCOMP_FILTER_FLAG_SPEC_ALLOW (#2430) because libseccomp-golang does not support it yet.

It does; calling filter.SetSSB(true) will enable SECCOMP_FILTER_FLAG_SPEC_ALLOW.

Comment on lines 1024 to 1025
switch flag {
case "SECCOMP_FILTER_FLAG_LOG":
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be nice to not have this set of flags handled in two separate places. Perhaps we can add some common part to libcontainer/seccomp?

While at it, adding SCMP_FLTATR_CTL_OPTIMIZE would be awesome

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right now we have four supported flags following the same naming convention supported by the SECCOMP_SET_MODE_FILTER operation.

SECCOMP_FILTER_FLAG_LOG
SECCOMP_FILTER_FLAG_NEW_LISTENER
SECCOMP_FILTER_FLAG_SPEC_ALLOW
SECCOMP_FILTER_FLAG_TSYNC

How would SCMP_FLTATR_CTL_OPTIMIZE map to that?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While at it, adding SCMP_FLTATR_CTL_OPTIMIZE would be awesome

The set of flags listed in the runtime-spec is a subset of the flag supported by the Linux API in the seccomp syscall:

flags (array of strings, OPTIONAL) - list of flags to use with seccomp(2).

A valid list of constants is shown below.

SECCOMP_FILTER_FLAG_TSYNC
SECCOMP_FILTER_FLAG_LOG
SECCOMP_FILTER_FLAG_SPEC_ALLOW

SCMP_FLTATR_CTL_OPTIMIZE is part of libseccomp API but not part of the Linux API. It is not in the runtime-spec because container runtimes don't have to use libseccomp. Are you suggesting runc should support it even if it's not in the spec?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be nice to not have this set of flags handled in two separate places. Perhaps we can add some common part to libcontainer/seccomp?

Now that I have added the 2 additional flags, the code looks different, and I don't see how to add some common part to libcontainer/seccomp... any suggestions?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re SCMP_FLTATR_CTL_OPTIMIZE.

Perhaps runc should just set it to 2 unconditionally. Also, this is orthogonal to this PR, so nevermind.

newConfig := new(configs.Seccomp)
newConfig.Syscalls = []*configs.Syscall{}

// We don't currently support all seccomp flags.
for _, flag := range config.Flags {
switch flag {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's add support for SECCOMP_FILTER_FLAG_SPEC_ALLOW as well as SECCOMP_FILTER_FLAG_TSYNC

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SECCOMP_FILTER_FLAG_TSYNC is there already and it's on by default (in libseccomp-golang). How would it be supported? Do you mean "let's explicitly ignore it", as I see no other way.

saschagrunert added a commit to saschagrunert/common that referenced this pull request Feb 23, 2022
crun supports seccomp filter flags since containers/crun@fefabff
runc will get them with opencontainers/runc#3390
youki will get them with containers/youki#733

To support them generally, we now copy the flags during the seccomp
setup, otherwise they will get lost.

Signed-off-by: Sascha Grunert <[email protected]>
// Add extra flags
for _, flag := range config.Flags {
switch flag {
case "SECCOMP_FILTER_FLAG_TSYNC":
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: I think we should have them as consts in the runtime spec. I proposed that change in opencontainers/runtime-spec#1138

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that seccomp-golang sets this flag unconditionally, and we (runc/libcontainer/seccomp/patchbpf) do not set this at all (not sure if this was by design or just forgotten; @cyphar WDYT?)

From what I see, it seems that for runc it does not make sense to do so, as we execute runc init right after applying seccomp rules, and it does not matter much whether these rules were applied to all threads or not.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There was an issue with setting it in patchbpf, I can't remember the exact details.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SECCOMP_FILTER_FLAG_TSYNC is not a flag on the bpf instructions but a flag for the seccomp() syscall, so I don't think patchbpf can do something with it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TSYNC is set by libseccomp-golang by default, and there's no way to remove it. So adding it here does not make sense.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, OK, here we're ignoring it, which I guess is a good thing to do.

saschagrunert
saschagrunert previously approved these changes Feb 23, 2022
Comment on lines 105 to 100
@test "runc run [seccomp] (SECCOMP_FILTER_FLAG_TSYNC)" {
update_config ' .process.args = ["/bin/sh", "-c", "mkdir /dev/shm/foo"]
| .process.noNewPrivileges = false
| .linux.seccomp = {
"defaultAction":"SCMP_ACT_ALLOW",
"architectures":["SCMP_ARCH_X86","SCMP_ARCH_X32"],
"flags":["SECCOMP_FILTER_FLAG_TSYNC"],
"syscalls":[{"names":["mkdir"], "action":"SCMP_ACT_ERRNO"}]
}'

# This test checks that the tsync flag is accepted
runc run test_busybox
[ "$status" -ne 0 ]
[[ "$output" == *"mkdir:"*"/dev/shm/foo"*"Operation not permitted"* ]]
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't like the same code being repeated 3 times. Can probably factor it out to a function accepting the list of flags. That way we can also test a combination of flags, not just individual ones.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated with a loop to test all set of flags possible

@kolyshkin
Copy link
Contributor

One other thing -- I don't think it makes any sense to expose SECCOMP_FILTER_FLAG_TSYNC.

@alban
Copy link
Contributor Author

alban commented May 6, 2022

Sorry I didn't follow up on this PR.

As a side note, I noticed we will have a new flag soon: SECCOMP_FILTER_FLAG_WAIT_KILLABLE_RECV
https://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git/commit/?id=c2aa2dfef243
But it's not in a Linux release yet. So runc should add it later in a different PR.
Edit: it is in Linux 5.19-rc1

@alban alban changed the title seccomp: add support for SECCOMP_FILTER_FLAG_LOG seccomp: add support for flags Jun 27, 2022
@alban
Copy link
Contributor Author

alban commented Jun 27, 2022

I rebased, updated the PR description and commitmsg. I think it is ready for another review.

@vnsavage
Copy link

vnsavage commented Jul 15, 2022

It seems like all requested changes are implemented on this PR? Is there anything else that needs doing before this gets merged?

@AkihiroSuda AkihiroSuda added this to the 1.2.0 milestone Jul 16, 2022
@alban
Copy link
Contributor Author

alban commented Jul 19, 2022

It seems my last update in this PR reliably breaks TestUsernsCheckpoint. Any ideas why?

@kolyshkin
Copy link
Contributor

The error is EINVAL from move_mount(2) syscall. It can be returned if the kernel is too old, but it seems that

  • Linux v5.15 is used, which is sufficient;
  • criu does the check for the MOVE_MOUNT_SET_GROUP feature and finds it working.

There are other cases when the move mount set group can return EINVAL, but it does not seem likely.

Ah! It might be caused by the fact that criu ppa comes with criu 3.17-1ppa2.20.04 which is old (should be 3.17.1). I just saw that @rst0git updated that package 3 hours ago. So, let me restart the CI.

@kolyshkin
Copy link
Contributor

TestUsernsCheckpoint also fails on CentOS Stream 9, although with a different diagnostics (from https://cirrus-ci.com/task/5426803694108672?logs=unit_tests#L1368):

    checkpoint_test.go:163: (00.041591) pie: 1: restoring lsm profile (current) unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
    checkpoint_test.go:163: (00.041654) Error (criu/cr-restore.c:1510): 65454 stopped by signal 11: Segmentation fault
    checkpoint_test.go:163: (00.042114) mnt: Switching to new ns to clean ghosts
    checkpoint_test.go:163: (00.042270) uns: calling exit_usernsd (-1, 1)
    checkpoint_test.go:163: (00.042312) uns: daemon calls 0x47fe40 (65452, -1, 1)
    checkpoint_test.go:163: (00.042319) uns: `- daemon exits w/ 0
    checkpoint_test.go:163: (00.042824) uns: daemon stopped
    checkpoint_test.go:163: (00.042829) Error (criu/cr-restore.c:2536): Restoring FAILED.
    checkpoint_test.go:163: === END ===

@kolyshkin
Copy link
Contributor

@alban you also need to fix a linter warning

@alban
Copy link
Contributor Author

alban commented Jul 20, 2022

  • PR updated and rebased.
  • The linter warning is fixed.
  • The TestUsernsCheckpoint issue is resolved in github-actions but there is still an issue in cirrus-ci with TestUsernsCheckpoint and TestCheckpoint.

@rst0git
Copy link
Contributor

rst0git commented Jul 20, 2022

TestUsernsCheckpoint also fails on CentOS Stream 9, although with a different diagnostics (from https://cirrus-ci.com/task/5426803694108672?logs=unit_tests#L1368):

We recently updated the criu package in CentOS Stream (#3532)

kolyshkin
kolyshkin previously approved these changes Jul 20, 2022
Copy link
Contributor

@kolyshkin kolyshkin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM (CI failure is unrelated and is being addressed in #3532)

AkihiroSuda
AkihiroSuda previously approved these changes Jul 21, 2022
@AkihiroSuda
Copy link
Member

Required statuses must pass before merging

Can't hit the merge button :(

@rata
Copy link
Member

rata commented Jul 22, 2022

Again --- FAIL: TestUsernsCheckpoint (0.43s). I guess @alban needs to push again (or maybe rebase) so the tests are happy? Or is the problem on the CI not fixed?

@alban
Copy link
Contributor Author

alban commented Jul 25, 2022

I don't have the rights to restart the Cirrus CI. I could force-push to run the CI again but I would lose the 2 approvals. Should I do that?

However I don't think that would work: #3532 (comment) says the criu RPM should show up in the CentOS repositories after 1 week but https://gitlab.com/redhat/centos-stream/rpms/criu/-/merge_requests/12 was merged on July 12th, so almost 2 weeks ago and I ran a test of this runc branch on a fork today and it still fail with the same error.

@rata
Copy link
Member

rata commented Jul 28, 2022

@alban a fix was just merged for the test (#3539). If you rebase and push, the tests should re-start and work this time :)

Signed-off-by: Alban Crequy <[email protected]>
List of seccomp flags defined in runtime-spec:
* SECCOMP_FILTER_FLAG_TSYNC
* SECCOMP_FILTER_FLAG_LOG
* SECCOMP_FILTER_FLAG_SPEC_ALLOW

Note that runc does not apply SECCOMP_FILTER_FLAG_TSYNC. It does not
make sense to apply the seccomp filter on only one thread; other threads
will be terminated after exec anyway.

See similar commit in crun:
containers/crun@fefabff

Note that SECCOMP_FILTER_FLAG_WAIT_KILLABLE_RECV (introduced by
https://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git/commit/?id=c2aa2dfef243
in Linux 5.19-rc1) is not added yet because Linux 5.19 is not released
yet.

Signed-off-by: Alban Crequy <[email protected]>
@alban
Copy link
Contributor Author

alban commented Jul 28, 2022

@rata updated!

Copy link
Contributor

@kolyshkin kolyshkin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants