From 152d342a8d11d9ff4cee4eaab5b91f42501794f0 Mon Sep 17 00:00:00 2001 From: Davanum Srinivas Date: Fri, 25 Oct 2024 20:05:11 -0400 Subject: [PATCH] Update to latest cadvisor Signed-off-by: Davanum Srinivas --- .../checkpoint-restore/go-criu/v5/LICENSE | 205 -- .../github.com/containerd/console/LICENSE | 195 -- .../seccomp/libseccomp-golang/LICENSE | 26 - .../github.com/syndtr/gocapability/LICENSE | 28 - go.mod | 5 +- go.sum | 15 +- go.work.sum | 3 + .../checkpoint-restore/go-criu/v5/.gitignore | 6 - .../go-criu/v5/.golangci.yml | 12 - .../checkpoint-restore/go-criu/v5/LICENSE | 201 -- .../checkpoint-restore/go-criu/v5/Makefile | 107 - .../checkpoint-restore/go-criu/v5/README.md | 96 - .../checkpoint-restore/go-criu/v5/features.go | 45 - .../checkpoint-restore/go-criu/v5/main.go | 264 -- .../checkpoint-restore/go-criu/v5/notify.go | 62 - .../go-criu/v5/rpc/rpc.pb.go | 2237 ---------------- .../go-criu/v5/rpc/rpc.proto | 239 -- .../containerd/console/.golangci.yml | 20 - vendor/github.com/containerd/console/LICENSE | 191 -- .../github.com/containerd/console/README.md | 29 - .../github.com/containerd/console/console.go | 90 - .../containerd/console/console_linux.go | 281 -- .../containerd/console/console_other.go | 36 - .../containerd/console/console_unix.go | 157 -- .../containerd/console/console_windows.go | 219 -- .../containerd/console/pty_freebsd_cgo.go | 46 - .../containerd/console/pty_freebsd_nocgo.go | 37 - .../github.com/containerd/console/pty_unix.go | 31 - .../github.com/containerd/console/pty_zos.go | 43 - .../containerd/console/tc_darwin.go | 44 - .../containerd/console/tc_freebsd_cgo.go | 58 - .../containerd/console/tc_freebsd_nocgo.go | 56 - .../github.com/containerd/console/tc_linux.go | 51 - .../containerd/console/tc_netbsd.go | 45 - .../containerd/console/tc_openbsd_cgo.go | 52 - .../containerd/console/tc_openbsd_nocgo.go | 48 - .../github.com/containerd/console/tc_unix.go | 92 - .../github.com/containerd/console/tc_zos.go | 39 - .../container/libcontainer/handler.go | 35 +- .../google/cadvisor/utils/sysfs/sysfs.go | 6 +- .../runc/libcontainer/README.md | 318 --- .../opencontainers/runc/libcontainer/SPEC.md | 465 ---- .../runc/libcontainer/apparmor/apparmor.go | 16 - .../libcontainer/apparmor/apparmor_linux.go | 68 - .../apparmor/apparmor_unsupported.go | 15 - .../libcontainer/capabilities/capabilities.go | 123 - .../capabilities/capabilities_unsupported.go | 4 - .../libcontainer/configs/validate/rootless.go | 86 - .../configs/validate/validator.go | 306 --- .../runc/libcontainer/console_linux.go | 41 - .../runc/libcontainer/container.go | 130 - .../runc/libcontainer/container_linux.go | 2267 ----------------- .../runc/libcontainer/criu_opts_linux.go | 34 - .../runc/libcontainer/eaccess_go119.go | 17 - .../runc/libcontainer/eaccess_stub.go | 10 - .../opencontainers/runc/libcontainer/error.go | 13 - .../runc/libcontainer/factory.go | 30 - .../runc/libcontainer/factory_linux.go | 402 --- .../runc/libcontainer/init_linux.go | 641 ----- .../runc/libcontainer/keys/keyctl.go | 45 - .../runc/libcontainer/logs/logs.go | 56 - .../runc/libcontainer/message_linux.go | 97 - .../runc/libcontainer/mount_linux.go | 101 - .../runc/libcontainer/network_linux.go | 100 - .../runc/libcontainer/notify_linux.go | 84 - .../runc/libcontainer/notify_v2_linux.go | 80 - .../runc/libcontainer/process.go | 126 - .../runc/libcontainer/process_linux.go | 823 ------ .../runc/libcontainer/restored_process.go | 128 - .../runc/libcontainer/rootfs_linux.go | 1155 --------- .../runc/libcontainer/seccomp/config.go | 113 - .../seccomp/patchbpf/enosys_linux.go | 721 ------ .../seccomp/patchbpf/enosys_unsupported.go | 4 - .../libcontainer/seccomp/seccomp_linux.go | 268 -- .../seccomp/seccomp_unsupported.go | 28 - .../runc/libcontainer/setns_init_linux.go | 149 -- .../runc/libcontainer/standard_init_linux.go | 282 -- .../runc/libcontainer/state_linux.go | 243 -- .../runc/libcontainer/stats_linux.go | 13 - .../opencontainers/runc/libcontainer/sync.go | 126 - .../opencontainers/runc/types/events.go | 155 -- .../seccomp/libseccomp-golang/.gitignore | 4 - .../seccomp/libseccomp-golang/.golangci.yml | 4 - .../seccomp/libseccomp-golang/CHANGELOG | 42 - .../seccomp/libseccomp-golang/CONTRIBUTING.md | 120 - .../seccomp/libseccomp-golang/LICENSE | 22 - .../seccomp/libseccomp-golang/Makefile | 31 - .../seccomp/libseccomp-golang/README.md | 59 - .../seccomp/libseccomp-golang/SECURITY.md | 48 - .../seccomp/libseccomp-golang/seccomp.go | 1188 --------- .../libseccomp-golang/seccomp_internal.go | 884 ------- vendor/github.com/syndtr/gocapability/LICENSE | 24 - .../gocapability/capability/capability.go | 133 - .../capability/capability_linux.go | 642 ----- .../capability/capability_noop.go | 19 - .../syndtr/gocapability/capability/enum.go | 309 --- .../gocapability/capability/enum_gen.go | 138 - .../gocapability/capability/syscall_linux.go | 154 -- vendor/golang.org/x/net/bpf/asm.go | 41 - vendor/golang.org/x/net/bpf/constants.go | 222 -- vendor/golang.org/x/net/bpf/doc.go | 80 - vendor/golang.org/x/net/bpf/instructions.go | 726 ------ vendor/golang.org/x/net/bpf/setter.go | 10 - vendor/golang.org/x/net/bpf/vm.go | 150 -- .../golang.org/x/net/bpf/vm_instructions.go | 182 -- vendor/modules.txt | 23 +- 106 files changed, 13 insertions(+), 20577 deletions(-) delete mode 100644 LICENSES/vendor/github.com/checkpoint-restore/go-criu/v5/LICENSE delete mode 100644 LICENSES/vendor/github.com/containerd/console/LICENSE delete mode 100644 LICENSES/vendor/github.com/seccomp/libseccomp-golang/LICENSE delete mode 100644 LICENSES/vendor/github.com/syndtr/gocapability/LICENSE delete mode 100644 vendor/github.com/checkpoint-restore/go-criu/v5/.gitignore delete mode 100644 vendor/github.com/checkpoint-restore/go-criu/v5/.golangci.yml delete mode 100644 vendor/github.com/checkpoint-restore/go-criu/v5/LICENSE delete mode 100644 vendor/github.com/checkpoint-restore/go-criu/v5/Makefile delete mode 100644 vendor/github.com/checkpoint-restore/go-criu/v5/README.md delete mode 100644 vendor/github.com/checkpoint-restore/go-criu/v5/features.go delete mode 100644 vendor/github.com/checkpoint-restore/go-criu/v5/main.go delete mode 100644 vendor/github.com/checkpoint-restore/go-criu/v5/notify.go delete mode 100644 vendor/github.com/checkpoint-restore/go-criu/v5/rpc/rpc.pb.go delete mode 100644 vendor/github.com/checkpoint-restore/go-criu/v5/rpc/rpc.proto delete mode 100644 vendor/github.com/containerd/console/.golangci.yml delete mode 100644 vendor/github.com/containerd/console/LICENSE delete mode 100644 vendor/github.com/containerd/console/README.md delete mode 100644 vendor/github.com/containerd/console/console.go delete mode 100644 vendor/github.com/containerd/console/console_linux.go delete mode 100644 vendor/github.com/containerd/console/console_other.go delete mode 100644 vendor/github.com/containerd/console/console_unix.go delete mode 100644 vendor/github.com/containerd/console/console_windows.go delete mode 100644 vendor/github.com/containerd/console/pty_freebsd_cgo.go delete mode 100644 vendor/github.com/containerd/console/pty_freebsd_nocgo.go delete mode 100644 vendor/github.com/containerd/console/pty_unix.go delete mode 100644 vendor/github.com/containerd/console/pty_zos.go delete mode 100644 vendor/github.com/containerd/console/tc_darwin.go delete mode 100644 vendor/github.com/containerd/console/tc_freebsd_cgo.go delete mode 100644 vendor/github.com/containerd/console/tc_freebsd_nocgo.go delete mode 100644 vendor/github.com/containerd/console/tc_linux.go delete mode 100644 vendor/github.com/containerd/console/tc_netbsd.go delete mode 100644 vendor/github.com/containerd/console/tc_openbsd_cgo.go delete mode 100644 vendor/github.com/containerd/console/tc_openbsd_nocgo.go delete mode 100644 vendor/github.com/containerd/console/tc_unix.go delete mode 100644 vendor/github.com/containerd/console/tc_zos.go delete mode 100644 vendor/github.com/opencontainers/runc/libcontainer/README.md delete mode 100644 vendor/github.com/opencontainers/runc/libcontainer/SPEC.md delete mode 100644 vendor/github.com/opencontainers/runc/libcontainer/apparmor/apparmor.go delete mode 100644 vendor/github.com/opencontainers/runc/libcontainer/apparmor/apparmor_linux.go delete mode 100644 vendor/github.com/opencontainers/runc/libcontainer/apparmor/apparmor_unsupported.go delete mode 100644 vendor/github.com/opencontainers/runc/libcontainer/capabilities/capabilities.go delete mode 100644 vendor/github.com/opencontainers/runc/libcontainer/capabilities/capabilities_unsupported.go delete mode 100644 vendor/github.com/opencontainers/runc/libcontainer/configs/validate/rootless.go delete mode 100644 vendor/github.com/opencontainers/runc/libcontainer/configs/validate/validator.go delete mode 100644 vendor/github.com/opencontainers/runc/libcontainer/console_linux.go delete mode 100644 vendor/github.com/opencontainers/runc/libcontainer/container.go delete mode 100644 vendor/github.com/opencontainers/runc/libcontainer/container_linux.go delete mode 100644 vendor/github.com/opencontainers/runc/libcontainer/criu_opts_linux.go delete mode 100644 vendor/github.com/opencontainers/runc/libcontainer/eaccess_go119.go delete mode 100644 vendor/github.com/opencontainers/runc/libcontainer/eaccess_stub.go delete mode 100644 vendor/github.com/opencontainers/runc/libcontainer/error.go delete mode 100644 vendor/github.com/opencontainers/runc/libcontainer/factory.go delete mode 100644 vendor/github.com/opencontainers/runc/libcontainer/factory_linux.go delete mode 100644 vendor/github.com/opencontainers/runc/libcontainer/init_linux.go delete mode 100644 vendor/github.com/opencontainers/runc/libcontainer/keys/keyctl.go delete mode 100644 vendor/github.com/opencontainers/runc/libcontainer/logs/logs.go delete mode 100644 vendor/github.com/opencontainers/runc/libcontainer/message_linux.go delete mode 100644 vendor/github.com/opencontainers/runc/libcontainer/mount_linux.go delete mode 100644 vendor/github.com/opencontainers/runc/libcontainer/network_linux.go delete mode 100644 vendor/github.com/opencontainers/runc/libcontainer/notify_linux.go delete mode 100644 vendor/github.com/opencontainers/runc/libcontainer/notify_v2_linux.go delete mode 100644 vendor/github.com/opencontainers/runc/libcontainer/process.go delete mode 100644 vendor/github.com/opencontainers/runc/libcontainer/process_linux.go delete mode 100644 vendor/github.com/opencontainers/runc/libcontainer/restored_process.go delete mode 100644 vendor/github.com/opencontainers/runc/libcontainer/rootfs_linux.go delete mode 100644 vendor/github.com/opencontainers/runc/libcontainer/seccomp/config.go delete mode 100644 vendor/github.com/opencontainers/runc/libcontainer/seccomp/patchbpf/enosys_linux.go delete mode 100644 vendor/github.com/opencontainers/runc/libcontainer/seccomp/patchbpf/enosys_unsupported.go delete mode 100644 vendor/github.com/opencontainers/runc/libcontainer/seccomp/seccomp_linux.go delete mode 100644 vendor/github.com/opencontainers/runc/libcontainer/seccomp/seccomp_unsupported.go delete mode 100644 vendor/github.com/opencontainers/runc/libcontainer/setns_init_linux.go delete mode 100644 vendor/github.com/opencontainers/runc/libcontainer/standard_init_linux.go delete mode 100644 vendor/github.com/opencontainers/runc/libcontainer/state_linux.go delete mode 100644 vendor/github.com/opencontainers/runc/libcontainer/stats_linux.go delete mode 100644 vendor/github.com/opencontainers/runc/libcontainer/sync.go delete mode 100644 vendor/github.com/opencontainers/runc/types/events.go delete mode 100644 vendor/github.com/seccomp/libseccomp-golang/.gitignore delete mode 100644 vendor/github.com/seccomp/libseccomp-golang/.golangci.yml delete mode 100644 vendor/github.com/seccomp/libseccomp-golang/CHANGELOG delete mode 100644 vendor/github.com/seccomp/libseccomp-golang/CONTRIBUTING.md delete mode 100644 vendor/github.com/seccomp/libseccomp-golang/LICENSE delete mode 100644 vendor/github.com/seccomp/libseccomp-golang/Makefile delete mode 100644 vendor/github.com/seccomp/libseccomp-golang/README.md delete mode 100644 vendor/github.com/seccomp/libseccomp-golang/SECURITY.md delete mode 100644 vendor/github.com/seccomp/libseccomp-golang/seccomp.go delete mode 100644 vendor/github.com/seccomp/libseccomp-golang/seccomp_internal.go delete mode 100644 vendor/github.com/syndtr/gocapability/LICENSE delete mode 100644 vendor/github.com/syndtr/gocapability/capability/capability.go delete mode 100644 vendor/github.com/syndtr/gocapability/capability/capability_linux.go delete mode 100644 vendor/github.com/syndtr/gocapability/capability/capability_noop.go delete mode 100644 vendor/github.com/syndtr/gocapability/capability/enum.go delete mode 100644 vendor/github.com/syndtr/gocapability/capability/enum_gen.go delete mode 100644 vendor/github.com/syndtr/gocapability/capability/syscall_linux.go delete mode 100644 vendor/golang.org/x/net/bpf/asm.go delete mode 100644 vendor/golang.org/x/net/bpf/constants.go delete mode 100644 vendor/golang.org/x/net/bpf/doc.go delete mode 100644 vendor/golang.org/x/net/bpf/instructions.go delete mode 100644 vendor/golang.org/x/net/bpf/setter.go delete mode 100644 vendor/golang.org/x/net/bpf/vm.go delete mode 100644 vendor/golang.org/x/net/bpf/vm_instructions.go diff --git a/LICENSES/vendor/github.com/checkpoint-restore/go-criu/v5/LICENSE b/LICENSES/vendor/github.com/checkpoint-restore/go-criu/v5/LICENSE deleted file mode 100644 index 029457c8ae9..00000000000 --- a/LICENSES/vendor/github.com/checkpoint-restore/go-criu/v5/LICENSE +++ /dev/null @@ -1,205 +0,0 @@ -= vendor/github.com/checkpoint-restore/go-criu/v5 licensed under: = - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright {yyyy} {name of copyright owner} - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - -= vendor/github.com/checkpoint-restore/go-criu/v5/LICENSE e3fc50a88d0a364313df4b21ef20c29e diff --git a/LICENSES/vendor/github.com/containerd/console/LICENSE b/LICENSES/vendor/github.com/containerd/console/LICENSE deleted file mode 100644 index 6819f0725c3..00000000000 --- a/LICENSES/vendor/github.com/containerd/console/LICENSE +++ /dev/null @@ -1,195 +0,0 @@ -= vendor/github.com/containerd/console licensed under: = - - - Apache License - Version 2.0, January 2004 - https://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - Copyright The containerd Authors - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - https://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - -= vendor/github.com/containerd/console/LICENSE 1269f40c0d099c21a871163984590d89 diff --git a/LICENSES/vendor/github.com/seccomp/libseccomp-golang/LICENSE b/LICENSES/vendor/github.com/seccomp/libseccomp-golang/LICENSE deleted file mode 100644 index 51eca510235..00000000000 --- a/LICENSES/vendor/github.com/seccomp/libseccomp-golang/LICENSE +++ /dev/null @@ -1,26 +0,0 @@ -= vendor/github.com/seccomp/libseccomp-golang licensed under: = - -Copyright (c) 2015 Matthew Heon -Copyright (c) 2015 Paul Moore -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: -- Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -= vendor/github.com/seccomp/libseccomp-golang/LICENSE 343b433e752e8b44a543cdf61f14b628 diff --git a/LICENSES/vendor/github.com/syndtr/gocapability/LICENSE b/LICENSES/vendor/github.com/syndtr/gocapability/LICENSE deleted file mode 100644 index 253de550720..00000000000 --- a/LICENSES/vendor/github.com/syndtr/gocapability/LICENSE +++ /dev/null @@ -1,28 +0,0 @@ -= vendor/github.com/syndtr/gocapability licensed under: = - -Copyright 2013 Suryandaru Triandana -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -= vendor/github.com/syndtr/gocapability/LICENSE a7304f5073e7be4ba7bffabbf9f2bbca diff --git a/go.mod b/go.mod index e83a7ef781f..16f68dddf3d 100644 --- a/go.mod +++ b/go.mod @@ -34,7 +34,7 @@ require ( github.com/gogo/protobuf v1.3.2 github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da github.com/golang/protobuf v1.5.4 - github.com/google/cadvisor v0.50.0 + github.com/google/cadvisor v0.51.0 github.com/google/cel-go v0.21.0 github.com/google/gnostic-models v0.6.8 github.com/google/go-cmp v0.6.0 @@ -134,9 +134,7 @@ require ( github.com/cenkalti/backoff/v4 v4.3.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/chai2010/gettext-go v1.0.2 // indirect - github.com/checkpoint-restore/go-criu/v5 v5.3.0 // indirect github.com/cilium/ebpf v0.11.0 // indirect - github.com/containerd/console v1.0.4 // indirect github.com/containerd/containerd/api v1.7.19 // indirect github.com/containerd/errdefs v0.1.0 // indirect github.com/containerd/log v0.1.0 // indirect @@ -196,7 +194,6 @@ require ( github.com/soheilhy/cmux v0.1.5 // indirect github.com/stoewer/go-strcase v1.3.0 // indirect github.com/stretchr/objx v0.5.2 // indirect - github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 // indirect github.com/tmc/grpc-websocket-proxy v0.0.0-20220101234140-673ab2c3ae75 // indirect github.com/x448/float16 v0.8.4 // indirect github.com/xiang90/probing v0.0.0-20221125231312-a49e3df8f510 // indirect diff --git a/go.sum b/go.sum index 9593719be78..e1da9b0f274 100644 --- a/go.sum +++ b/go.sum @@ -169,7 +169,6 @@ github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UF github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chai2010/gettext-go v1.0.2 h1:1Lwwip6Q2QGsAdl/ZKPCwTe9fe0CjlUbqj5bFNSjIRk= github.com/chai2010/gettext-go v1.0.2/go.mod h1:y+wnP2cHYaVj19NZhYKAwEMH2CI1gNHeQQ+5AjwawxA= -github.com/checkpoint-restore/go-criu/v5 v5.3.0 h1:wpFFOoomK3389ue2lAb0Boag6XPht5QYpipxmSNL4d8= github.com/checkpoint-restore/go-criu/v5 v5.3.0/go.mod h1:E/eQpaFtUKGOOSEBZgmKAcn+zUUwWxqcaKZlF54wK8E= github.com/chzyer/readline v1.5.1/go.mod h1:Eh+b79XXUwfKfcPLepksvw2tcLE/Ct21YObkaSkeBlk= github.com/cilium/ebpf v0.11.0 h1:V8gS/bTCCjX9uUnkUFUpPsksM8n1lXBAvHcpiFk1X2Y= @@ -183,8 +182,7 @@ github.com/container-storage-interface/spec v1.9.0 h1:zKtX4STsq31Knz3gciCYCi1SXt github.com/container-storage-interface/spec v1.9.0/go.mod h1:ZfDu+3ZRyeVqxZM0Ds19MVLkN2d1XJ5MAfi1L3VjlT0= github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaDFBM= github.com/containerd/cgroups v1.1.0/go.mod h1:6ppBcbh/NOOUU+dMKrykgaBnK9lCIBxHqJDGwsa1mIw= -github.com/containerd/console v1.0.4 h1:F2g4+oChYvBTsASRTz8NP6iIAi97J3TtSAsLbIFn4ro= -github.com/containerd/console v1.0.4/go.mod h1:YynlIjWYF8myEu6sdkwKIvGQq+cOckRm6So2avqoYAk= +github.com/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U= github.com/containerd/containerd/api v1.7.19 h1:VWbJL+8Ap4Ju2mx9c9qS1uFSB1OVYr5JJrW2yT5vFoA= github.com/containerd/containerd/api v1.7.19/go.mod h1:fwGavl3LNwAV5ilJ0sbrABL44AQxmNjDRcwheXDb6Ig= github.com/containerd/errdefs v0.1.0 h1:m0wCRBiu1WJT/Fr+iOoQHMQS/eP5myQ8lCv4Dz5ZURM= @@ -299,7 +297,6 @@ github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:W github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/golangplus/bytes v0.0.0-20160111154220-45c989fe5450/go.mod h1:Bk6SMAONeMXrxql8uvOKuAZSu8aM5RUGv+1C6IJaEho= @@ -309,8 +306,8 @@ github.com/golangplus/testing v1.0.0 h1:+ZeeiKZENNOMkTTELoSySazi+XaEhVO0mb+eanrS github.com/golangplus/testing v1.0.0/go.mod h1:ZDreixUV3YzhoVraIDyOzHrr76p6NUh6k/pPg/Q3gYA= github.com/google/btree v1.0.1 h1:gK4Kx5IaGY9CD5sPJ36FHiBJ6ZXl0kilRiiCj+jdYp4= github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA= -github.com/google/cadvisor v0.50.0 h1:7w/hKIbJKBWqQsRTy+Hpj2vj+fnxrLXcEXFy+LW0Bsg= -github.com/google/cadvisor v0.50.0/go.mod h1:VxCDwZalpFyENvmfabFqaIGsqNKLtDzE62a19rfVTB8= +github.com/google/cadvisor v0.51.0 h1:BspqSPdZoLKrnvuZNOvM/KiJ/A+RdixwagN20n+2H8k= +github.com/google/cadvisor v0.51.0/go.mod h1:czGE/c/P/i0QFpVNKTFrIEzord9Y10YfpwuaSWXELc0= github.com/google/cel-go v0.21.0 h1:cl6uW/gxN+Hy50tNYvI691+sXxioCnstFzLp2WO4GCI= github.com/google/cel-go v0.21.0/go.mod h1:rHUlWCcBKgyEk+eV03RPdZUekPp6YcJwV0FxuUksYxc= github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I= @@ -321,7 +318,6 @@ github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= @@ -492,7 +488,6 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 h1:kdXcSzyDtseVEc4yCz2qF8ZrQvIDBJLl4S1c3GCXmoI= github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= github.com/tmc/grpc-websocket-proxy v0.0.0-20220101234140-673ab2c3ae75 h1:6fotK7otjonDflCTK0BCfls4SPy3NcCVb5dqqmbRknE= github.com/tmc/grpc-websocket-proxy v0.0.0-20220101234140-673ab2c3ae75/go.mod h1:KO6IkyS8Y3j8OdNO85qEYBsRPuteD+YciPomcXdrMnk= @@ -614,12 +609,10 @@ golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= @@ -681,8 +674,6 @@ google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2 google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= -google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/go.work.sum b/go.work.sum index 7220e056cfa..c2f6a59e338 100644 --- a/go.work.sum +++ b/go.work.sum @@ -134,10 +134,12 @@ github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.2 h1:ORnrOK0C4WmYV/uYt3koHEWB github.com/aws/aws-sdk-go-v2/service/sts v1.30.1 h1:+woJ607dllHJQtsnJLi52ycuqHMwlW+Wqm2Ppsfp4nQ= github.com/aws/smithy-go v1.20.3 h1:ryHwveWzPV5BIof6fyDvor6V3iUL7nTfiTKXHiW05nE= github.com/census-instrumentation/opencensus-proto v0.4.1 h1:iKLQ0xPNFxR/2hzXZMrBo8f1j86j5WHzznCCQxV/b8g= +github.com/checkpoint-restore/go-criu/v5 v5.3.0 h1:wpFFOoomK3389ue2lAb0Boag6XPht5QYpipxmSNL4d8= github.com/chzyer/readline v1.5.1 h1:upd/6fQk4src78LMRzh5vItIt361/o4uq553V8B5sGI= github.com/client9/misspell v0.3.4 h1:ta993UF76GwbvJcIo3Y68y/M3WxlpEHPWIGDkJYwzJI= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f h1:WBZRG4aNOuI15bLRrCgN8fCq8E5Xuty6jGbmSNEvSsU= github.com/cncf/xds/go v0.0.0-20240423153145-555b57ec207b h1:ga8SEFjZ60pxLcmhnThWgvH2wg8376yUJmPhEH4H3kw= +github.com/containerd/console v1.0.3 h1:lIr7SlA5PxZyMV30bDW0MGbiOPXwc63yRuCP0ARubLw= github.com/envoyproxy/go-control-plane v0.12.0 h1:4X+VP1GHd1Mhj6IB5mMeGbLCleqxjletLK6K0rbxyZI= github.com/envoyproxy/protoc-gen-validate v1.0.4 h1:gVPz/FMfvh57HdSJQyvBtF00j8JU4zdyUgIUNhlgg0A= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 h1:BHsljHzVlRcyQhjrss6TZTdY2VfCqZPbv5k3iBFa2ZQ= @@ -165,6 +167,7 @@ github.com/opentracing/opentracing-go v1.1.0 h1:pWlfV3Bxv7k65HYwkikxat0+s3pV4bsq github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e h1:aoZm08cpOy4WuID//EZDgcC4zIxODThtZNPirFr42+A= github.com/rogpeppe/fastuuid v1.2.0 h1:Ppwyp6VYCF1nvBTXL3trRso7mXMlRrw9ooo375wvi2s= github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo= +github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 h1:kdXcSzyDtseVEc4yCz2qF8ZrQvIDBJLl4S1c3GCXmoI= github.com/urfave/cli v1.22.1 h1:+mkCCcOFKPnCmVYVcURKps1Xe+3zP90gSYGNfRkjoIY= github.com/xhit/go-str2duration/v2 v2.1.0 h1:lxklc02Drh6ynqX+DdPyp5pCKLUQpRT8bp8Ydu2Bstc= github.com/yuin/goldmark v1.4.13 h1:fVcFKWvrslecOb/tg+Cc05dkeYx540o0FuFt3nUVDoE= diff --git a/vendor/github.com/checkpoint-restore/go-criu/v5/.gitignore b/vendor/github.com/checkpoint-restore/go-criu/v5/.gitignore deleted file mode 100644 index 1b87ff10e6b..00000000000 --- a/vendor/github.com/checkpoint-restore/go-criu/v5/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -test/test -test/test.coverage -test/piggie/piggie -test/phaul/phaul -test/phaul/phaul.coverage -image diff --git a/vendor/github.com/checkpoint-restore/go-criu/v5/.golangci.yml b/vendor/github.com/checkpoint-restore/go-criu/v5/.golangci.yml deleted file mode 100644 index fbbac4b4173..00000000000 --- a/vendor/github.com/checkpoint-restore/go-criu/v5/.golangci.yml +++ /dev/null @@ -1,12 +0,0 @@ -run: - skip_dirs: - - rpc - - stats - -linters: - disable-all: false - presets: - - bugs - - performance - - unused - - format diff --git a/vendor/github.com/checkpoint-restore/go-criu/v5/LICENSE b/vendor/github.com/checkpoint-restore/go-criu/v5/LICENSE deleted file mode 100644 index 8dada3edaf5..00000000000 --- a/vendor/github.com/checkpoint-restore/go-criu/v5/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright {yyyy} {name of copyright owner} - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/vendor/github.com/checkpoint-restore/go-criu/v5/Makefile b/vendor/github.com/checkpoint-restore/go-criu/v5/Makefile deleted file mode 100644 index 67c43a05b32..00000000000 --- a/vendor/github.com/checkpoint-restore/go-criu/v5/Makefile +++ /dev/null @@ -1,107 +0,0 @@ -SHELL = /bin/bash -GO ?= go -CC ?= gcc -COVERAGE_PATH ?= $(shell pwd)/.coverage -CRIU_FEATURE_MEM_TRACK = $(shell if criu check --feature mem_dirty_track > /dev/null; then echo 1; else echo 0; fi) -CRIU_FEATURE_LAZY_PAGES = $(shell if criu check --feature uffd-noncoop > /dev/null; then echo 1; else echo 0; fi) -CRIU_FEATURE_PIDFD_STORE = $(shell if criu check --feature pidfd_store > /dev/null; then echo 1; else echo 0; fi) - -export CRIU_FEATURE_MEM_TRACK CRIU_FEATURE_LAZY_PAGES CRIU_FEATURE_PIDFD_STORE - -all: build test phaul-test - -lint: - golangci-lint run ./... - -build: - $(GO) build -v ./... - -TEST_PAYLOAD := test/piggie/piggie -TEST_BINARIES := test/test $(TEST_PAYLOAD) test/phaul/phaul -COVERAGE_BINARIES := test/test.coverage test/phaul/phaul.coverage -test-bin: $(TEST_BINARIES) - -test/piggie/piggie: test/piggie/piggie.c - $(CC) $^ -o $@ - -test/test: test/main.go - $(GO) build -v -o $@ $^ - -test: $(TEST_BINARIES) - mkdir -p image - PID=$$(test/piggie/piggie) && { \ - test/test dump $$PID image && \ - test/test restore image; \ - pkill -9 piggie; \ - } - rm -rf image - -test/phaul/phaul: test/phaul/main.go - $(GO) build -v -o $@ $^ - -phaul-test: $(TEST_BINARIES) - rm -rf image - PID=$$(test/piggie/piggie) && { \ - test/phaul/phaul $$PID; \ - pkill -9 piggie; \ - } - -test/test.coverage: test/*.go - $(GO) test \ - -covermode=count \ - -coverpkg=./... \ - -mod=vendor \ - -tags coverage \ - -buildmode=pie -c -o $@ $^ - -test/phaul/phaul.coverage: test/phaul/*.go - $(GO) test \ - -covermode=count \ - -coverpkg=./... \ - -mod=vendor \ - -tags coverage \ - -buildmode=pie -c -o $@ $^ - -coverage: $(COVERAGE_BINARIES) $(TEST_PAYLOAD) - mkdir -p $(COVERAGE_PATH) - mkdir -p image - PID=$$(test/piggie/piggie) && { \ - test/test.coverage -test.coverprofile=coverprofile.integration.$$RANDOM -test.outputdir=${COVERAGE_PATH} COVERAGE dump $$PID image && \ - test/test.coverage -test.coverprofile=coverprofile.integration.$$RANDOM -test.outputdir=${COVERAGE_PATH} COVERAGE restore image; \ - pkill -9 piggie; \ - } - rm -rf image - PID=$$(test/piggie/piggie) && { \ - test/phaul/phaul.coverage -test.coverprofile=coverprofile.integration.$$RANDOM -test.outputdir=${COVERAGE_PATH} COVERAGE $$PID; \ - pkill -9 piggie; \ - } - echo "mode: set" > .coverage/coverage.out && cat .coverage/coverprofile* | \ - grep -v mode: | sort -r | awk '{if($$1 != last) {print $$0;last=$$1}}' >> .coverage/coverage.out - -clean: - @rm -f $(TEST_BINARIES) $(COVERAGE_BINARIES) codecov - @rm -rf image $(COVERAGE_PATH) - -rpc/rpc.proto: - curl -sSL https://raw.githubusercontent.com/checkpoint-restore/criu/master/images/rpc.proto -o $@ - -stats/stats.proto: - curl -sSL https://raw.githubusercontent.com/checkpoint-restore/criu/master/images/stats.proto -o $@ - -rpc/rpc.pb.go: rpc/rpc.proto - protoc --go_out=. --go_opt=M$^=rpc/ $^ - -stats/stats.pb.go: stats/stats.proto - protoc --go_out=. --go_opt=M$^=stats/ $^ - -vendor: - GO111MODULE=on $(GO) mod tidy - GO111MODULE=on $(GO) mod vendor - GO111MODULE=on $(GO) mod verify - -codecov: - curl -Os https://uploader.codecov.io/latest/linux/codecov - chmod +x codecov - ./codecov -f '.coverage/coverage.out' - -.PHONY: build test phaul-test test-bin clean lint vendor coverage codecov diff --git a/vendor/github.com/checkpoint-restore/go-criu/v5/README.md b/vendor/github.com/checkpoint-restore/go-criu/v5/README.md deleted file mode 100644 index a7483321b5c..00000000000 --- a/vendor/github.com/checkpoint-restore/go-criu/v5/README.md +++ /dev/null @@ -1,96 +0,0 @@ -[![test](https://github.com/checkpoint-restore/go-criu/workflows/ci/badge.svg?branch=master)](https://github.com/checkpoint-restore/go-criu/actions?query=workflow%3Aci) -[![verify](https://github.com/checkpoint-restore/go-criu/workflows/verify/badge.svg?branch=master)](https://github.com/checkpoint-restore/go-criu/actions?query=workflow%3Averify) -[![Go Reference](https://pkg.go.dev/badge/github.com/checkpoint-restore/go-criu.svg)](https://pkg.go.dev/github.com/checkpoint-restore/go-criu) - -## go-criu -- Go bindings for CRIU - -This repository provides Go bindings for [CRIU](https://criu.org/). The code is based on the Go-based PHaul -implementation from the CRIU repository. For easier inclusion into other Go projects the -CRIU Go bindings have been moved to this repository. - -The Go bindings provide an easy way to use the CRIU RPC calls from Go without the need -to set up all the infrastructure to make the actual RPC connection to CRIU. - -The following example would print the version of CRIU: -```go -import ( - "log" - - "github.com/checkpoint-restore/go-criu/v5" -) - -func main() { - c := criu.MakeCriu() - version, err := c.GetCriuVersion() - if err != nil { - log.Fatalln(err) - } - log.Println(version) -} -``` - -or to just check if at least a certain CRIU version is installed: - -```go - c := criu.MakeCriu() - result, err := c.IsCriuAtLeast(31100) -``` - -## Releases - -The first go-criu release was 3.11 based on CRIU 3.11. The initial plan -was to follow CRIU so that go-criu would carry the same version number as -CRIU. - -As go-criu is imported in other projects and as Go modules are expected -to follow Semantic Versioning go-criu will also follow Semantic Versioning -starting with the 4.0.0 release. - -The following table shows the relation between go-criu and criu versions: - -| Major version | Latest release | CRIU version | -| -------------- | -------------- | ------------ | -| v5             | 5.2.0         | 3.16         | -| v5             | 5.0.0         | 3.15         | -| v4             | 4.1.0         | 3.14         | - -## How to contribute - -While bug fixes can first be identified via an "issue", that is not required. -It's ok to just open up a PR with the fix, but make sure you include the same -information you would have included in an issue - like how to reproduce it. - -PRs for new features should include some background on what use cases the -new code is trying to address. When possible and when it makes sense, try to -break-up larger PRs into smaller ones - it's easier to review smaller -code changes. But only if those smaller ones make sense as stand-alone PRs. - -Regardless of the type of PR, all PRs should include: -* well documented code changes -* additional testcases. Ideally, they should fail w/o your code change applied -* documentation changes - -Squash your commits into logical pieces of work that might want to be reviewed -separate from the rest of the PRs. Ideally, each commit should implement a -single idea, and the PR branch should pass the tests at every commit. GitHub -makes it easy to review the cumulative effect of many commits; so, when in -doubt, use smaller commits. - -PRs that fix issues should include a reference like `Closes #XXXX` in the -commit message so that github will automatically close the referenced issue -when the PR is merged. - -Contributors must assert that they are in compliance with the [Developer -Certificate of Origin 1.1](http://developercertificate.org/). This is achieved -by adding a "Signed-off-by" line containing the contributor's name and e-mail -to every commit message. Your signature certifies that you wrote the patch or -otherwise have the right to pass it on as an open-source patch. - -### License and copyright - -Unless mentioned otherwise in a specific file's header, all code in -this project is released under the Apache 2.0 license. - -The author of a change remains the copyright holder of their code -(no copyright assignment). The list of authors and contributors can be -retrieved from the git commit history and in some cases, the file headers. diff --git a/vendor/github.com/checkpoint-restore/go-criu/v5/features.go b/vendor/github.com/checkpoint-restore/go-criu/v5/features.go deleted file mode 100644 index c7127f95157..00000000000 --- a/vendor/github.com/checkpoint-restore/go-criu/v5/features.go +++ /dev/null @@ -1,45 +0,0 @@ -package criu - -import ( - "fmt" - - "github.com/checkpoint-restore/go-criu/v5/rpc" -) - -// Feature checking in go-criu is based on the libcriu feature checking function. - -// Feature checking allows the user to check if CRIU supports -// certain features. There are CRIU features which do not depend -// on the version of CRIU but on kernel features or architecture. -// -// One example is memory tracking. Memory tracking can be disabled -// in the kernel or there are architectures which do not support -// it (aarch64 for example). By using the feature check a libcriu -// user can easily query CRIU if a certain feature is available. -// -// The features which should be checked can be marked in the -// structure 'struct criu_feature_check'. Each structure member -// that is set to true will result in CRIU checking for the -// availability of that feature in the current combination of -// CRIU/kernel/architecture. -// -// Available features will be set to true when the function -// returns successfully. Missing features will be set to false. - -func (c *Criu) FeatureCheck(features *rpc.CriuFeatures) (*rpc.CriuFeatures, error) { - resp, err := c.doSwrkWithResp( - rpc.CriuReqType_FEATURE_CHECK, - nil, - nil, - features, - ) - if err != nil { - return nil, err - } - - if resp.GetType() != rpc.CriuReqType_FEATURE_CHECK { - return nil, fmt.Errorf("Unexpected CRIU RPC response") - } - - return features, nil -} diff --git a/vendor/github.com/checkpoint-restore/go-criu/v5/main.go b/vendor/github.com/checkpoint-restore/go-criu/v5/main.go deleted file mode 100644 index 88b1b24587a..00000000000 --- a/vendor/github.com/checkpoint-restore/go-criu/v5/main.go +++ /dev/null @@ -1,264 +0,0 @@ -package criu - -import ( - "errors" - "fmt" - "os" - "os/exec" - "strconv" - "syscall" - - "github.com/checkpoint-restore/go-criu/v5/rpc" - "google.golang.org/protobuf/proto" -) - -// Criu struct -type Criu struct { - swrkCmd *exec.Cmd - swrkSk *os.File - swrkPath string -} - -// MakeCriu returns the Criu object required for most operations -func MakeCriu() *Criu { - return &Criu{ - swrkPath: "criu", - } -} - -// SetCriuPath allows setting the path to the CRIU binary -// if it is in a non standard location -func (c *Criu) SetCriuPath(path string) { - c.swrkPath = path -} - -// Prepare sets up everything for the RPC communication to CRIU -func (c *Criu) Prepare() error { - fds, err := syscall.Socketpair(syscall.AF_LOCAL, syscall.SOCK_SEQPACKET, 0) - if err != nil { - return err - } - - cln := os.NewFile(uintptr(fds[0]), "criu-xprt-cln") - syscall.CloseOnExec(fds[0]) - srv := os.NewFile(uintptr(fds[1]), "criu-xprt-srv") - defer srv.Close() - - args := []string{"swrk", strconv.Itoa(fds[1])} - // #nosec G204 - cmd := exec.Command(c.swrkPath, args...) - - err = cmd.Start() - if err != nil { - cln.Close() - return err - } - - c.swrkCmd = cmd - c.swrkSk = cln - - return nil -} - -// Cleanup cleans up -func (c *Criu) Cleanup() { - if c.swrkCmd != nil { - c.swrkSk.Close() - c.swrkSk = nil - _ = c.swrkCmd.Wait() - c.swrkCmd = nil - } -} - -func (c *Criu) sendAndRecv(reqB []byte) ([]byte, int, error) { - cln := c.swrkSk - _, err := cln.Write(reqB) - if err != nil { - return nil, 0, err - } - - respB := make([]byte, 2*4096) - n, err := cln.Read(respB) - if err != nil { - return nil, 0, err - } - - return respB, n, nil -} - -func (c *Criu) doSwrk(reqType rpc.CriuReqType, opts *rpc.CriuOpts, nfy Notify) error { - resp, err := c.doSwrkWithResp(reqType, opts, nfy, nil) - if err != nil { - return err - } - respType := resp.GetType() - if respType != reqType { - return errors.New("unexpected CRIU RPC response") - } - - return nil -} - -func (c *Criu) doSwrkWithResp(reqType rpc.CriuReqType, opts *rpc.CriuOpts, nfy Notify, features *rpc.CriuFeatures) (*rpc.CriuResp, error) { - var resp *rpc.CriuResp - - req := rpc.CriuReq{ - Type: &reqType, - Opts: opts, - } - - if nfy != nil { - opts.NotifyScripts = proto.Bool(true) - } - - if features != nil { - req.Features = features - } - - if c.swrkCmd == nil { - err := c.Prepare() - if err != nil { - return nil, err - } - - defer c.Cleanup() - } - - for { - reqB, err := proto.Marshal(&req) - if err != nil { - return nil, err - } - - respB, respS, err := c.sendAndRecv(reqB) - if err != nil { - return nil, err - } - - resp = &rpc.CriuResp{} - err = proto.Unmarshal(respB[:respS], resp) - if err != nil { - return nil, err - } - - if !resp.GetSuccess() { - return resp, fmt.Errorf("operation failed (msg:%s err:%d)", - resp.GetCrErrmsg(), resp.GetCrErrno()) - } - - respType := resp.GetType() - if respType != rpc.CriuReqType_NOTIFY { - break - } - if nfy == nil { - return resp, errors.New("unexpected notify") - } - - notify := resp.GetNotify() - switch notify.GetScript() { - case "pre-dump": - err = nfy.PreDump() - case "post-dump": - err = nfy.PostDump() - case "pre-restore": - err = nfy.PreRestore() - case "post-restore": - err = nfy.PostRestore(notify.GetPid()) - case "network-lock": - err = nfy.NetworkLock() - case "network-unlock": - err = nfy.NetworkUnlock() - case "setup-namespaces": - err = nfy.SetupNamespaces(notify.GetPid()) - case "post-setup-namespaces": - err = nfy.PostSetupNamespaces() - case "post-resume": - err = nfy.PostResume() - default: - err = nil - } - - if err != nil { - return resp, err - } - - req = rpc.CriuReq{ - Type: &respType, - NotifySuccess: proto.Bool(true), - } - } - - return resp, nil -} - -// Dump dumps a process -func (c *Criu) Dump(opts *rpc.CriuOpts, nfy Notify) error { - return c.doSwrk(rpc.CriuReqType_DUMP, opts, nfy) -} - -// Restore restores a process -func (c *Criu) Restore(opts *rpc.CriuOpts, nfy Notify) error { - return c.doSwrk(rpc.CriuReqType_RESTORE, opts, nfy) -} - -// PreDump does a pre-dump -func (c *Criu) PreDump(opts *rpc.CriuOpts, nfy Notify) error { - return c.doSwrk(rpc.CriuReqType_PRE_DUMP, opts, nfy) -} - -// StartPageServer starts the page server -func (c *Criu) StartPageServer(opts *rpc.CriuOpts) error { - return c.doSwrk(rpc.CriuReqType_PAGE_SERVER, opts, nil) -} - -// StartPageServerChld starts the page server and returns PID and port -func (c *Criu) StartPageServerChld(opts *rpc.CriuOpts) (int, int, error) { - resp, err := c.doSwrkWithResp(rpc.CriuReqType_PAGE_SERVER_CHLD, opts, nil, nil) - if err != nil { - return 0, 0, err - } - - return int(resp.Ps.GetPid()), int(resp.Ps.GetPort()), nil -} - -// GetCriuVersion executes the VERSION RPC call and returns the version -// as an integer. Major * 10000 + Minor * 100 + SubLevel -func (c *Criu) GetCriuVersion() (int, error) { - resp, err := c.doSwrkWithResp(rpc.CriuReqType_VERSION, nil, nil, nil) - if err != nil { - return 0, err - } - - if resp.GetType() != rpc.CriuReqType_VERSION { - return 0, fmt.Errorf("Unexpected CRIU RPC response") - } - - version := int(*resp.GetVersion().MajorNumber) * 10000 - version += int(*resp.GetVersion().MinorNumber) * 100 - if resp.GetVersion().Sublevel != nil { - version += int(*resp.GetVersion().Sublevel) - } - - if resp.GetVersion().Gitid != nil { - // taken from runc: if it is a git release -> increase minor by 1 - version -= (version % 100) - version += 100 - } - - return version, nil -} - -// IsCriuAtLeast checks if the version is at least the same -// as the parameter version -func (c *Criu) IsCriuAtLeast(version int) (bool, error) { - criuVersion, err := c.GetCriuVersion() - if err != nil { - return false, err - } - - if criuVersion >= version { - return true, nil - } - - return false, nil -} diff --git a/vendor/github.com/checkpoint-restore/go-criu/v5/notify.go b/vendor/github.com/checkpoint-restore/go-criu/v5/notify.go deleted file mode 100644 index a177f2bb5c0..00000000000 --- a/vendor/github.com/checkpoint-restore/go-criu/v5/notify.go +++ /dev/null @@ -1,62 +0,0 @@ -package criu - -// Notify interface -type Notify interface { - PreDump() error - PostDump() error - PreRestore() error - PostRestore(pid int32) error - NetworkLock() error - NetworkUnlock() error - SetupNamespaces(pid int32) error - PostSetupNamespaces() error - PostResume() error -} - -// NoNotify struct -type NoNotify struct{} - -// PreDump NoNotify -func (c NoNotify) PreDump() error { - return nil -} - -// PostDump NoNotify -func (c NoNotify) PostDump() error { - return nil -} - -// PreRestore NoNotify -func (c NoNotify) PreRestore() error { - return nil -} - -// PostRestore NoNotify -func (c NoNotify) PostRestore(pid int32) error { - return nil -} - -// NetworkLock NoNotify -func (c NoNotify) NetworkLock() error { - return nil -} - -// NetworkUnlock NoNotify -func (c NoNotify) NetworkUnlock() error { - return nil -} - -// SetupNamespaces NoNotify -func (c NoNotify) SetupNamespaces(pid int32) error { - return nil -} - -// PostSetupNamespaces NoNotify -func (c NoNotify) PostSetupNamespaces() error { - return nil -} - -// PostResume NoNotify -func (c NoNotify) PostResume() error { - return nil -} diff --git a/vendor/github.com/checkpoint-restore/go-criu/v5/rpc/rpc.pb.go b/vendor/github.com/checkpoint-restore/go-criu/v5/rpc/rpc.pb.go deleted file mode 100644 index 15e33fea52f..00000000000 --- a/vendor/github.com/checkpoint-restore/go-criu/v5/rpc/rpc.pb.go +++ /dev/null @@ -1,2237 +0,0 @@ -// SPDX-License-Identifier: MIT - -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.27.1 -// protoc v3.12.4 -// source: rpc/rpc.proto - -package rpc - -import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -type CriuCgMode int32 - -const ( - CriuCgMode_IGNORE CriuCgMode = 0 - CriuCgMode_CG_NONE CriuCgMode = 1 - CriuCgMode_PROPS CriuCgMode = 2 - CriuCgMode_SOFT CriuCgMode = 3 - CriuCgMode_FULL CriuCgMode = 4 - CriuCgMode_STRICT CriuCgMode = 5 - CriuCgMode_DEFAULT CriuCgMode = 6 -) - -// Enum value maps for CriuCgMode. -var ( - CriuCgMode_name = map[int32]string{ - 0: "IGNORE", - 1: "CG_NONE", - 2: "PROPS", - 3: "SOFT", - 4: "FULL", - 5: "STRICT", - 6: "DEFAULT", - } - CriuCgMode_value = map[string]int32{ - "IGNORE": 0, - "CG_NONE": 1, - "PROPS": 2, - "SOFT": 3, - "FULL": 4, - "STRICT": 5, - "DEFAULT": 6, - } -) - -func (x CriuCgMode) Enum() *CriuCgMode { - p := new(CriuCgMode) - *p = x - return p -} - -func (x CriuCgMode) String() string { - return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) -} - -func (CriuCgMode) Descriptor() protoreflect.EnumDescriptor { - return file_rpc_rpc_proto_enumTypes[0].Descriptor() -} - -func (CriuCgMode) Type() protoreflect.EnumType { - return &file_rpc_rpc_proto_enumTypes[0] -} - -func (x CriuCgMode) Number() protoreflect.EnumNumber { - return protoreflect.EnumNumber(x) -} - -// Deprecated: Do not use. -func (x *CriuCgMode) UnmarshalJSON(b []byte) error { - num, err := protoimpl.X.UnmarshalJSONEnum(x.Descriptor(), b) - if err != nil { - return err - } - *x = CriuCgMode(num) - return nil -} - -// Deprecated: Use CriuCgMode.Descriptor instead. -func (CriuCgMode) EnumDescriptor() ([]byte, []int) { - return file_rpc_rpc_proto_rawDescGZIP(), []int{0} -} - -type CriuPreDumpMode int32 - -const ( - CriuPreDumpMode_SPLICE CriuPreDumpMode = 1 - CriuPreDumpMode_VM_READ CriuPreDumpMode = 2 -) - -// Enum value maps for CriuPreDumpMode. -var ( - CriuPreDumpMode_name = map[int32]string{ - 1: "SPLICE", - 2: "VM_READ", - } - CriuPreDumpMode_value = map[string]int32{ - "SPLICE": 1, - "VM_READ": 2, - } -) - -func (x CriuPreDumpMode) Enum() *CriuPreDumpMode { - p := new(CriuPreDumpMode) - *p = x - return p -} - -func (x CriuPreDumpMode) String() string { - return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) -} - -func (CriuPreDumpMode) Descriptor() protoreflect.EnumDescriptor { - return file_rpc_rpc_proto_enumTypes[1].Descriptor() -} - -func (CriuPreDumpMode) Type() protoreflect.EnumType { - return &file_rpc_rpc_proto_enumTypes[1] -} - -func (x CriuPreDumpMode) Number() protoreflect.EnumNumber { - return protoreflect.EnumNumber(x) -} - -// Deprecated: Do not use. -func (x *CriuPreDumpMode) UnmarshalJSON(b []byte) error { - num, err := protoimpl.X.UnmarshalJSONEnum(x.Descriptor(), b) - if err != nil { - return err - } - *x = CriuPreDumpMode(num) - return nil -} - -// Deprecated: Use CriuPreDumpMode.Descriptor instead. -func (CriuPreDumpMode) EnumDescriptor() ([]byte, []int) { - return file_rpc_rpc_proto_rawDescGZIP(), []int{1} -} - -type CriuReqType int32 - -const ( - CriuReqType_EMPTY CriuReqType = 0 - CriuReqType_DUMP CriuReqType = 1 - CriuReqType_RESTORE CriuReqType = 2 - CriuReqType_CHECK CriuReqType = 3 - CriuReqType_PRE_DUMP CriuReqType = 4 - CriuReqType_PAGE_SERVER CriuReqType = 5 - CriuReqType_NOTIFY CriuReqType = 6 - CriuReqType_CPUINFO_DUMP CriuReqType = 7 - CriuReqType_CPUINFO_CHECK CriuReqType = 8 - CriuReqType_FEATURE_CHECK CriuReqType = 9 - CriuReqType_VERSION CriuReqType = 10 - CriuReqType_WAIT_PID CriuReqType = 11 - CriuReqType_PAGE_SERVER_CHLD CriuReqType = 12 -) - -// Enum value maps for CriuReqType. -var ( - CriuReqType_name = map[int32]string{ - 0: "EMPTY", - 1: "DUMP", - 2: "RESTORE", - 3: "CHECK", - 4: "PRE_DUMP", - 5: "PAGE_SERVER", - 6: "NOTIFY", - 7: "CPUINFO_DUMP", - 8: "CPUINFO_CHECK", - 9: "FEATURE_CHECK", - 10: "VERSION", - 11: "WAIT_PID", - 12: "PAGE_SERVER_CHLD", - } - CriuReqType_value = map[string]int32{ - "EMPTY": 0, - "DUMP": 1, - "RESTORE": 2, - "CHECK": 3, - "PRE_DUMP": 4, - "PAGE_SERVER": 5, - "NOTIFY": 6, - "CPUINFO_DUMP": 7, - "CPUINFO_CHECK": 8, - "FEATURE_CHECK": 9, - "VERSION": 10, - "WAIT_PID": 11, - "PAGE_SERVER_CHLD": 12, - } -) - -func (x CriuReqType) Enum() *CriuReqType { - p := new(CriuReqType) - *p = x - return p -} - -func (x CriuReqType) String() string { - return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) -} - -func (CriuReqType) Descriptor() protoreflect.EnumDescriptor { - return file_rpc_rpc_proto_enumTypes[2].Descriptor() -} - -func (CriuReqType) Type() protoreflect.EnumType { - return &file_rpc_rpc_proto_enumTypes[2] -} - -func (x CriuReqType) Number() protoreflect.EnumNumber { - return protoreflect.EnumNumber(x) -} - -// Deprecated: Do not use. -func (x *CriuReqType) UnmarshalJSON(b []byte) error { - num, err := protoimpl.X.UnmarshalJSONEnum(x.Descriptor(), b) - if err != nil { - return err - } - *x = CriuReqType(num) - return nil -} - -// Deprecated: Use CriuReqType.Descriptor instead. -func (CriuReqType) EnumDescriptor() ([]byte, []int) { - return file_rpc_rpc_proto_rawDescGZIP(), []int{2} -} - -type CriuPageServerInfo struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Address *string `protobuf:"bytes,1,opt,name=address" json:"address,omitempty"` - Port *int32 `protobuf:"varint,2,opt,name=port" json:"port,omitempty"` - Pid *int32 `protobuf:"varint,3,opt,name=pid" json:"pid,omitempty"` - Fd *int32 `protobuf:"varint,4,opt,name=fd" json:"fd,omitempty"` -} - -func (x *CriuPageServerInfo) Reset() { - *x = CriuPageServerInfo{} - if protoimpl.UnsafeEnabled { - mi := &file_rpc_rpc_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *CriuPageServerInfo) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*CriuPageServerInfo) ProtoMessage() {} - -func (x *CriuPageServerInfo) ProtoReflect() protoreflect.Message { - mi := &file_rpc_rpc_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use CriuPageServerInfo.ProtoReflect.Descriptor instead. -func (*CriuPageServerInfo) Descriptor() ([]byte, []int) { - return file_rpc_rpc_proto_rawDescGZIP(), []int{0} -} - -func (x *CriuPageServerInfo) GetAddress() string { - if x != nil && x.Address != nil { - return *x.Address - } - return "" -} - -func (x *CriuPageServerInfo) GetPort() int32 { - if x != nil && x.Port != nil { - return *x.Port - } - return 0 -} - -func (x *CriuPageServerInfo) GetPid() int32 { - if x != nil && x.Pid != nil { - return *x.Pid - } - return 0 -} - -func (x *CriuPageServerInfo) GetFd() int32 { - if x != nil && x.Fd != nil { - return *x.Fd - } - return 0 -} - -type CriuVethPair struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - IfIn *string `protobuf:"bytes,1,req,name=if_in,json=ifIn" json:"if_in,omitempty"` - IfOut *string `protobuf:"bytes,2,req,name=if_out,json=ifOut" json:"if_out,omitempty"` -} - -func (x *CriuVethPair) Reset() { - *x = CriuVethPair{} - if protoimpl.UnsafeEnabled { - mi := &file_rpc_rpc_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *CriuVethPair) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*CriuVethPair) ProtoMessage() {} - -func (x *CriuVethPair) ProtoReflect() protoreflect.Message { - mi := &file_rpc_rpc_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use CriuVethPair.ProtoReflect.Descriptor instead. -func (*CriuVethPair) Descriptor() ([]byte, []int) { - return file_rpc_rpc_proto_rawDescGZIP(), []int{1} -} - -func (x *CriuVethPair) GetIfIn() string { - if x != nil && x.IfIn != nil { - return *x.IfIn - } - return "" -} - -func (x *CriuVethPair) GetIfOut() string { - if x != nil && x.IfOut != nil { - return *x.IfOut - } - return "" -} - -type ExtMountMap struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Key *string `protobuf:"bytes,1,req,name=key" json:"key,omitempty"` - Val *string `protobuf:"bytes,2,req,name=val" json:"val,omitempty"` -} - -func (x *ExtMountMap) Reset() { - *x = ExtMountMap{} - if protoimpl.UnsafeEnabled { - mi := &file_rpc_rpc_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ExtMountMap) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ExtMountMap) ProtoMessage() {} - -func (x *ExtMountMap) ProtoReflect() protoreflect.Message { - mi := &file_rpc_rpc_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ExtMountMap.ProtoReflect.Descriptor instead. -func (*ExtMountMap) Descriptor() ([]byte, []int) { - return file_rpc_rpc_proto_rawDescGZIP(), []int{2} -} - -func (x *ExtMountMap) GetKey() string { - if x != nil && x.Key != nil { - return *x.Key - } - return "" -} - -func (x *ExtMountMap) GetVal() string { - if x != nil && x.Val != nil { - return *x.Val - } - return "" -} - -type JoinNamespace struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Ns *string `protobuf:"bytes,1,req,name=ns" json:"ns,omitempty"` - NsFile *string `protobuf:"bytes,2,req,name=ns_file,json=nsFile" json:"ns_file,omitempty"` - ExtraOpt *string `protobuf:"bytes,3,opt,name=extra_opt,json=extraOpt" json:"extra_opt,omitempty"` -} - -func (x *JoinNamespace) Reset() { - *x = JoinNamespace{} - if protoimpl.UnsafeEnabled { - mi := &file_rpc_rpc_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *JoinNamespace) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*JoinNamespace) ProtoMessage() {} - -func (x *JoinNamespace) ProtoReflect() protoreflect.Message { - mi := &file_rpc_rpc_proto_msgTypes[3] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use JoinNamespace.ProtoReflect.Descriptor instead. -func (*JoinNamespace) Descriptor() ([]byte, []int) { - return file_rpc_rpc_proto_rawDescGZIP(), []int{3} -} - -func (x *JoinNamespace) GetNs() string { - if x != nil && x.Ns != nil { - return *x.Ns - } - return "" -} - -func (x *JoinNamespace) GetNsFile() string { - if x != nil && x.NsFile != nil { - return *x.NsFile - } - return "" -} - -func (x *JoinNamespace) GetExtraOpt() string { - if x != nil && x.ExtraOpt != nil { - return *x.ExtraOpt - } - return "" -} - -type InheritFd struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Key *string `protobuf:"bytes,1,req,name=key" json:"key,omitempty"` - Fd *int32 `protobuf:"varint,2,req,name=fd" json:"fd,omitempty"` -} - -func (x *InheritFd) Reset() { - *x = InheritFd{} - if protoimpl.UnsafeEnabled { - mi := &file_rpc_rpc_proto_msgTypes[4] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *InheritFd) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*InheritFd) ProtoMessage() {} - -func (x *InheritFd) ProtoReflect() protoreflect.Message { - mi := &file_rpc_rpc_proto_msgTypes[4] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use InheritFd.ProtoReflect.Descriptor instead. -func (*InheritFd) Descriptor() ([]byte, []int) { - return file_rpc_rpc_proto_rawDescGZIP(), []int{4} -} - -func (x *InheritFd) GetKey() string { - if x != nil && x.Key != nil { - return *x.Key - } - return "" -} - -func (x *InheritFd) GetFd() int32 { - if x != nil && x.Fd != nil { - return *x.Fd - } - return 0 -} - -type CgroupRoot struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Ctrl *string `protobuf:"bytes,1,opt,name=ctrl" json:"ctrl,omitempty"` - Path *string `protobuf:"bytes,2,req,name=path" json:"path,omitempty"` -} - -func (x *CgroupRoot) Reset() { - *x = CgroupRoot{} - if protoimpl.UnsafeEnabled { - mi := &file_rpc_rpc_proto_msgTypes[5] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *CgroupRoot) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*CgroupRoot) ProtoMessage() {} - -func (x *CgroupRoot) ProtoReflect() protoreflect.Message { - mi := &file_rpc_rpc_proto_msgTypes[5] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use CgroupRoot.ProtoReflect.Descriptor instead. -func (*CgroupRoot) Descriptor() ([]byte, []int) { - return file_rpc_rpc_proto_rawDescGZIP(), []int{5} -} - -func (x *CgroupRoot) GetCtrl() string { - if x != nil && x.Ctrl != nil { - return *x.Ctrl - } - return "" -} - -func (x *CgroupRoot) GetPath() string { - if x != nil && x.Path != nil { - return *x.Path - } - return "" -} - -type UnixSk struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Inode *uint32 `protobuf:"varint,1,req,name=inode" json:"inode,omitempty"` -} - -func (x *UnixSk) Reset() { - *x = UnixSk{} - if protoimpl.UnsafeEnabled { - mi := &file_rpc_rpc_proto_msgTypes[6] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *UnixSk) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*UnixSk) ProtoMessage() {} - -func (x *UnixSk) ProtoReflect() protoreflect.Message { - mi := &file_rpc_rpc_proto_msgTypes[6] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use UnixSk.ProtoReflect.Descriptor instead. -func (*UnixSk) Descriptor() ([]byte, []int) { - return file_rpc_rpc_proto_rawDescGZIP(), []int{6} -} - -func (x *UnixSk) GetInode() uint32 { - if x != nil && x.Inode != nil { - return *x.Inode - } - return 0 -} - -type CriuOpts struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - ImagesDirFd *int32 `protobuf:"varint,1,req,name=images_dir_fd,json=imagesDirFd" json:"images_dir_fd,omitempty"` - Pid *int32 `protobuf:"varint,2,opt,name=pid" json:"pid,omitempty"` // if not set on dump, will dump requesting process - LeaveRunning *bool `protobuf:"varint,3,opt,name=leave_running,json=leaveRunning" json:"leave_running,omitempty"` - ExtUnixSk *bool `protobuf:"varint,4,opt,name=ext_unix_sk,json=extUnixSk" json:"ext_unix_sk,omitempty"` - TcpEstablished *bool `protobuf:"varint,5,opt,name=tcp_established,json=tcpEstablished" json:"tcp_established,omitempty"` - EvasiveDevices *bool `protobuf:"varint,6,opt,name=evasive_devices,json=evasiveDevices" json:"evasive_devices,omitempty"` - ShellJob *bool `protobuf:"varint,7,opt,name=shell_job,json=shellJob" json:"shell_job,omitempty"` - FileLocks *bool `protobuf:"varint,8,opt,name=file_locks,json=fileLocks" json:"file_locks,omitempty"` - LogLevel *int32 `protobuf:"varint,9,opt,name=log_level,json=logLevel,def=2" json:"log_level,omitempty"` - LogFile *string `protobuf:"bytes,10,opt,name=log_file,json=logFile" json:"log_file,omitempty"` // No subdirs are allowed. Consider using work-dir - Ps *CriuPageServerInfo `protobuf:"bytes,11,opt,name=ps" json:"ps,omitempty"` - NotifyScripts *bool `protobuf:"varint,12,opt,name=notify_scripts,json=notifyScripts" json:"notify_scripts,omitempty"` - Root *string `protobuf:"bytes,13,opt,name=root" json:"root,omitempty"` - ParentImg *string `protobuf:"bytes,14,opt,name=parent_img,json=parentImg" json:"parent_img,omitempty"` - TrackMem *bool `protobuf:"varint,15,opt,name=track_mem,json=trackMem" json:"track_mem,omitempty"` - AutoDedup *bool `protobuf:"varint,16,opt,name=auto_dedup,json=autoDedup" json:"auto_dedup,omitempty"` - WorkDirFd *int32 `protobuf:"varint,17,opt,name=work_dir_fd,json=workDirFd" json:"work_dir_fd,omitempty"` - LinkRemap *bool `protobuf:"varint,18,opt,name=link_remap,json=linkRemap" json:"link_remap,omitempty"` - Veths []*CriuVethPair `protobuf:"bytes,19,rep,name=veths" json:"veths,omitempty"` // DEPRECATED, use external instead - CpuCap *uint32 `protobuf:"varint,20,opt,name=cpu_cap,json=cpuCap,def=4294967295" json:"cpu_cap,omitempty"` - ForceIrmap *bool `protobuf:"varint,21,opt,name=force_irmap,json=forceIrmap" json:"force_irmap,omitempty"` - ExecCmd []string `protobuf:"bytes,22,rep,name=exec_cmd,json=execCmd" json:"exec_cmd,omitempty"` - ExtMnt []*ExtMountMap `protobuf:"bytes,23,rep,name=ext_mnt,json=extMnt" json:"ext_mnt,omitempty"` // DEPRECATED, use external instead - ManageCgroups *bool `protobuf:"varint,24,opt,name=manage_cgroups,json=manageCgroups" json:"manage_cgroups,omitempty"` // backward compatibility - CgRoot []*CgroupRoot `protobuf:"bytes,25,rep,name=cg_root,json=cgRoot" json:"cg_root,omitempty"` - RstSibling *bool `protobuf:"varint,26,opt,name=rst_sibling,json=rstSibling" json:"rst_sibling,omitempty"` // swrk only - InheritFd []*InheritFd `protobuf:"bytes,27,rep,name=inherit_fd,json=inheritFd" json:"inherit_fd,omitempty"` // swrk only - AutoExtMnt *bool `protobuf:"varint,28,opt,name=auto_ext_mnt,json=autoExtMnt" json:"auto_ext_mnt,omitempty"` - ExtSharing *bool `protobuf:"varint,29,opt,name=ext_sharing,json=extSharing" json:"ext_sharing,omitempty"` - ExtMasters *bool `protobuf:"varint,30,opt,name=ext_masters,json=extMasters" json:"ext_masters,omitempty"` - SkipMnt []string `protobuf:"bytes,31,rep,name=skip_mnt,json=skipMnt" json:"skip_mnt,omitempty"` - EnableFs []string `protobuf:"bytes,32,rep,name=enable_fs,json=enableFs" json:"enable_fs,omitempty"` - UnixSkIno []*UnixSk `protobuf:"bytes,33,rep,name=unix_sk_ino,json=unixSkIno" json:"unix_sk_ino,omitempty"` // DEPRECATED, use external instead - ManageCgroupsMode *CriuCgMode `protobuf:"varint,34,opt,name=manage_cgroups_mode,json=manageCgroupsMode,enum=CriuCgMode" json:"manage_cgroups_mode,omitempty"` - GhostLimit *uint32 `protobuf:"varint,35,opt,name=ghost_limit,json=ghostLimit,def=1048576" json:"ghost_limit,omitempty"` - IrmapScanPaths []string `protobuf:"bytes,36,rep,name=irmap_scan_paths,json=irmapScanPaths" json:"irmap_scan_paths,omitempty"` - External []string `protobuf:"bytes,37,rep,name=external" json:"external,omitempty"` - EmptyNs *uint32 `protobuf:"varint,38,opt,name=empty_ns,json=emptyNs" json:"empty_ns,omitempty"` - JoinNs []*JoinNamespace `protobuf:"bytes,39,rep,name=join_ns,json=joinNs" json:"join_ns,omitempty"` - CgroupProps *string `protobuf:"bytes,41,opt,name=cgroup_props,json=cgroupProps" json:"cgroup_props,omitempty"` - CgroupPropsFile *string `protobuf:"bytes,42,opt,name=cgroup_props_file,json=cgroupPropsFile" json:"cgroup_props_file,omitempty"` - CgroupDumpController []string `protobuf:"bytes,43,rep,name=cgroup_dump_controller,json=cgroupDumpController" json:"cgroup_dump_controller,omitempty"` - FreezeCgroup *string `protobuf:"bytes,44,opt,name=freeze_cgroup,json=freezeCgroup" json:"freeze_cgroup,omitempty"` - Timeout *uint32 `protobuf:"varint,45,opt,name=timeout" json:"timeout,omitempty"` - TcpSkipInFlight *bool `protobuf:"varint,46,opt,name=tcp_skip_in_flight,json=tcpSkipInFlight" json:"tcp_skip_in_flight,omitempty"` - WeakSysctls *bool `protobuf:"varint,47,opt,name=weak_sysctls,json=weakSysctls" json:"weak_sysctls,omitempty"` - LazyPages *bool `protobuf:"varint,48,opt,name=lazy_pages,json=lazyPages" json:"lazy_pages,omitempty"` - StatusFd *int32 `protobuf:"varint,49,opt,name=status_fd,json=statusFd" json:"status_fd,omitempty"` - OrphanPtsMaster *bool `protobuf:"varint,50,opt,name=orphan_pts_master,json=orphanPtsMaster" json:"orphan_pts_master,omitempty"` - ConfigFile *string `protobuf:"bytes,51,opt,name=config_file,json=configFile" json:"config_file,omitempty"` - TcpClose *bool `protobuf:"varint,52,opt,name=tcp_close,json=tcpClose" json:"tcp_close,omitempty"` - LsmProfile *string `protobuf:"bytes,53,opt,name=lsm_profile,json=lsmProfile" json:"lsm_profile,omitempty"` - TlsCacert *string `protobuf:"bytes,54,opt,name=tls_cacert,json=tlsCacert" json:"tls_cacert,omitempty"` - TlsCacrl *string `protobuf:"bytes,55,opt,name=tls_cacrl,json=tlsCacrl" json:"tls_cacrl,omitempty"` - TlsCert *string `protobuf:"bytes,56,opt,name=tls_cert,json=tlsCert" json:"tls_cert,omitempty"` - TlsKey *string `protobuf:"bytes,57,opt,name=tls_key,json=tlsKey" json:"tls_key,omitempty"` - Tls *bool `protobuf:"varint,58,opt,name=tls" json:"tls,omitempty"` - TlsNoCnVerify *bool `protobuf:"varint,59,opt,name=tls_no_cn_verify,json=tlsNoCnVerify" json:"tls_no_cn_verify,omitempty"` - CgroupYard *string `protobuf:"bytes,60,opt,name=cgroup_yard,json=cgroupYard" json:"cgroup_yard,omitempty"` - PreDumpMode *CriuPreDumpMode `protobuf:"varint,61,opt,name=pre_dump_mode,json=preDumpMode,enum=CriuPreDumpMode,def=1" json:"pre_dump_mode,omitempty"` - PidfdStoreSk *int32 `protobuf:"varint,62,opt,name=pidfd_store_sk,json=pidfdStoreSk" json:"pidfd_store_sk,omitempty"` - LsmMountContext *string `protobuf:"bytes,63,opt,name=lsm_mount_context,json=lsmMountContext" json:"lsm_mount_context,omitempty"` // optional bool check_mounts = 128; -} - -// Default values for CriuOpts fields. -const ( - Default_CriuOpts_LogLevel = int32(2) - Default_CriuOpts_CpuCap = uint32(4294967295) - Default_CriuOpts_GhostLimit = uint32(1048576) - Default_CriuOpts_PreDumpMode = CriuPreDumpMode_SPLICE -) - -func (x *CriuOpts) Reset() { - *x = CriuOpts{} - if protoimpl.UnsafeEnabled { - mi := &file_rpc_rpc_proto_msgTypes[7] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *CriuOpts) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*CriuOpts) ProtoMessage() {} - -func (x *CriuOpts) ProtoReflect() protoreflect.Message { - mi := &file_rpc_rpc_proto_msgTypes[7] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use CriuOpts.ProtoReflect.Descriptor instead. -func (*CriuOpts) Descriptor() ([]byte, []int) { - return file_rpc_rpc_proto_rawDescGZIP(), []int{7} -} - -func (x *CriuOpts) GetImagesDirFd() int32 { - if x != nil && x.ImagesDirFd != nil { - return *x.ImagesDirFd - } - return 0 -} - -func (x *CriuOpts) GetPid() int32 { - if x != nil && x.Pid != nil { - return *x.Pid - } - return 0 -} - -func (x *CriuOpts) GetLeaveRunning() bool { - if x != nil && x.LeaveRunning != nil { - return *x.LeaveRunning - } - return false -} - -func (x *CriuOpts) GetExtUnixSk() bool { - if x != nil && x.ExtUnixSk != nil { - return *x.ExtUnixSk - } - return false -} - -func (x *CriuOpts) GetTcpEstablished() bool { - if x != nil && x.TcpEstablished != nil { - return *x.TcpEstablished - } - return false -} - -func (x *CriuOpts) GetEvasiveDevices() bool { - if x != nil && x.EvasiveDevices != nil { - return *x.EvasiveDevices - } - return false -} - -func (x *CriuOpts) GetShellJob() bool { - if x != nil && x.ShellJob != nil { - return *x.ShellJob - } - return false -} - -func (x *CriuOpts) GetFileLocks() bool { - if x != nil && x.FileLocks != nil { - return *x.FileLocks - } - return false -} - -func (x *CriuOpts) GetLogLevel() int32 { - if x != nil && x.LogLevel != nil { - return *x.LogLevel - } - return Default_CriuOpts_LogLevel -} - -func (x *CriuOpts) GetLogFile() string { - if x != nil && x.LogFile != nil { - return *x.LogFile - } - return "" -} - -func (x *CriuOpts) GetPs() *CriuPageServerInfo { - if x != nil { - return x.Ps - } - return nil -} - -func (x *CriuOpts) GetNotifyScripts() bool { - if x != nil && x.NotifyScripts != nil { - return *x.NotifyScripts - } - return false -} - -func (x *CriuOpts) GetRoot() string { - if x != nil && x.Root != nil { - return *x.Root - } - return "" -} - -func (x *CriuOpts) GetParentImg() string { - if x != nil && x.ParentImg != nil { - return *x.ParentImg - } - return "" -} - -func (x *CriuOpts) GetTrackMem() bool { - if x != nil && x.TrackMem != nil { - return *x.TrackMem - } - return false -} - -func (x *CriuOpts) GetAutoDedup() bool { - if x != nil && x.AutoDedup != nil { - return *x.AutoDedup - } - return false -} - -func (x *CriuOpts) GetWorkDirFd() int32 { - if x != nil && x.WorkDirFd != nil { - return *x.WorkDirFd - } - return 0 -} - -func (x *CriuOpts) GetLinkRemap() bool { - if x != nil && x.LinkRemap != nil { - return *x.LinkRemap - } - return false -} - -func (x *CriuOpts) GetVeths() []*CriuVethPair { - if x != nil { - return x.Veths - } - return nil -} - -func (x *CriuOpts) GetCpuCap() uint32 { - if x != nil && x.CpuCap != nil { - return *x.CpuCap - } - return Default_CriuOpts_CpuCap -} - -func (x *CriuOpts) GetForceIrmap() bool { - if x != nil && x.ForceIrmap != nil { - return *x.ForceIrmap - } - return false -} - -func (x *CriuOpts) GetExecCmd() []string { - if x != nil { - return x.ExecCmd - } - return nil -} - -func (x *CriuOpts) GetExtMnt() []*ExtMountMap { - if x != nil { - return x.ExtMnt - } - return nil -} - -func (x *CriuOpts) GetManageCgroups() bool { - if x != nil && x.ManageCgroups != nil { - return *x.ManageCgroups - } - return false -} - -func (x *CriuOpts) GetCgRoot() []*CgroupRoot { - if x != nil { - return x.CgRoot - } - return nil -} - -func (x *CriuOpts) GetRstSibling() bool { - if x != nil && x.RstSibling != nil { - return *x.RstSibling - } - return false -} - -func (x *CriuOpts) GetInheritFd() []*InheritFd { - if x != nil { - return x.InheritFd - } - return nil -} - -func (x *CriuOpts) GetAutoExtMnt() bool { - if x != nil && x.AutoExtMnt != nil { - return *x.AutoExtMnt - } - return false -} - -func (x *CriuOpts) GetExtSharing() bool { - if x != nil && x.ExtSharing != nil { - return *x.ExtSharing - } - return false -} - -func (x *CriuOpts) GetExtMasters() bool { - if x != nil && x.ExtMasters != nil { - return *x.ExtMasters - } - return false -} - -func (x *CriuOpts) GetSkipMnt() []string { - if x != nil { - return x.SkipMnt - } - return nil -} - -func (x *CriuOpts) GetEnableFs() []string { - if x != nil { - return x.EnableFs - } - return nil -} - -func (x *CriuOpts) GetUnixSkIno() []*UnixSk { - if x != nil { - return x.UnixSkIno - } - return nil -} - -func (x *CriuOpts) GetManageCgroupsMode() CriuCgMode { - if x != nil && x.ManageCgroupsMode != nil { - return *x.ManageCgroupsMode - } - return CriuCgMode_IGNORE -} - -func (x *CriuOpts) GetGhostLimit() uint32 { - if x != nil && x.GhostLimit != nil { - return *x.GhostLimit - } - return Default_CriuOpts_GhostLimit -} - -func (x *CriuOpts) GetIrmapScanPaths() []string { - if x != nil { - return x.IrmapScanPaths - } - return nil -} - -func (x *CriuOpts) GetExternal() []string { - if x != nil { - return x.External - } - return nil -} - -func (x *CriuOpts) GetEmptyNs() uint32 { - if x != nil && x.EmptyNs != nil { - return *x.EmptyNs - } - return 0 -} - -func (x *CriuOpts) GetJoinNs() []*JoinNamespace { - if x != nil { - return x.JoinNs - } - return nil -} - -func (x *CriuOpts) GetCgroupProps() string { - if x != nil && x.CgroupProps != nil { - return *x.CgroupProps - } - return "" -} - -func (x *CriuOpts) GetCgroupPropsFile() string { - if x != nil && x.CgroupPropsFile != nil { - return *x.CgroupPropsFile - } - return "" -} - -func (x *CriuOpts) GetCgroupDumpController() []string { - if x != nil { - return x.CgroupDumpController - } - return nil -} - -func (x *CriuOpts) GetFreezeCgroup() string { - if x != nil && x.FreezeCgroup != nil { - return *x.FreezeCgroup - } - return "" -} - -func (x *CriuOpts) GetTimeout() uint32 { - if x != nil && x.Timeout != nil { - return *x.Timeout - } - return 0 -} - -func (x *CriuOpts) GetTcpSkipInFlight() bool { - if x != nil && x.TcpSkipInFlight != nil { - return *x.TcpSkipInFlight - } - return false -} - -func (x *CriuOpts) GetWeakSysctls() bool { - if x != nil && x.WeakSysctls != nil { - return *x.WeakSysctls - } - return false -} - -func (x *CriuOpts) GetLazyPages() bool { - if x != nil && x.LazyPages != nil { - return *x.LazyPages - } - return false -} - -func (x *CriuOpts) GetStatusFd() int32 { - if x != nil && x.StatusFd != nil { - return *x.StatusFd - } - return 0 -} - -func (x *CriuOpts) GetOrphanPtsMaster() bool { - if x != nil && x.OrphanPtsMaster != nil { - return *x.OrphanPtsMaster - } - return false -} - -func (x *CriuOpts) GetConfigFile() string { - if x != nil && x.ConfigFile != nil { - return *x.ConfigFile - } - return "" -} - -func (x *CriuOpts) GetTcpClose() bool { - if x != nil && x.TcpClose != nil { - return *x.TcpClose - } - return false -} - -func (x *CriuOpts) GetLsmProfile() string { - if x != nil && x.LsmProfile != nil { - return *x.LsmProfile - } - return "" -} - -func (x *CriuOpts) GetTlsCacert() string { - if x != nil && x.TlsCacert != nil { - return *x.TlsCacert - } - return "" -} - -func (x *CriuOpts) GetTlsCacrl() string { - if x != nil && x.TlsCacrl != nil { - return *x.TlsCacrl - } - return "" -} - -func (x *CriuOpts) GetTlsCert() string { - if x != nil && x.TlsCert != nil { - return *x.TlsCert - } - return "" -} - -func (x *CriuOpts) GetTlsKey() string { - if x != nil && x.TlsKey != nil { - return *x.TlsKey - } - return "" -} - -func (x *CriuOpts) GetTls() bool { - if x != nil && x.Tls != nil { - return *x.Tls - } - return false -} - -func (x *CriuOpts) GetTlsNoCnVerify() bool { - if x != nil && x.TlsNoCnVerify != nil { - return *x.TlsNoCnVerify - } - return false -} - -func (x *CriuOpts) GetCgroupYard() string { - if x != nil && x.CgroupYard != nil { - return *x.CgroupYard - } - return "" -} - -func (x *CriuOpts) GetPreDumpMode() CriuPreDumpMode { - if x != nil && x.PreDumpMode != nil { - return *x.PreDumpMode - } - return Default_CriuOpts_PreDumpMode -} - -func (x *CriuOpts) GetPidfdStoreSk() int32 { - if x != nil && x.PidfdStoreSk != nil { - return *x.PidfdStoreSk - } - return 0 -} - -func (x *CriuOpts) GetLsmMountContext() string { - if x != nil && x.LsmMountContext != nil { - return *x.LsmMountContext - } - return "" -} - -type CriuDumpResp struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Restored *bool `protobuf:"varint,1,opt,name=restored" json:"restored,omitempty"` -} - -func (x *CriuDumpResp) Reset() { - *x = CriuDumpResp{} - if protoimpl.UnsafeEnabled { - mi := &file_rpc_rpc_proto_msgTypes[8] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *CriuDumpResp) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*CriuDumpResp) ProtoMessage() {} - -func (x *CriuDumpResp) ProtoReflect() protoreflect.Message { - mi := &file_rpc_rpc_proto_msgTypes[8] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use CriuDumpResp.ProtoReflect.Descriptor instead. -func (*CriuDumpResp) Descriptor() ([]byte, []int) { - return file_rpc_rpc_proto_rawDescGZIP(), []int{8} -} - -func (x *CriuDumpResp) GetRestored() bool { - if x != nil && x.Restored != nil { - return *x.Restored - } - return false -} - -type CriuRestoreResp struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Pid *int32 `protobuf:"varint,1,req,name=pid" json:"pid,omitempty"` -} - -func (x *CriuRestoreResp) Reset() { - *x = CriuRestoreResp{} - if protoimpl.UnsafeEnabled { - mi := &file_rpc_rpc_proto_msgTypes[9] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *CriuRestoreResp) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*CriuRestoreResp) ProtoMessage() {} - -func (x *CriuRestoreResp) ProtoReflect() protoreflect.Message { - mi := &file_rpc_rpc_proto_msgTypes[9] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use CriuRestoreResp.ProtoReflect.Descriptor instead. -func (*CriuRestoreResp) Descriptor() ([]byte, []int) { - return file_rpc_rpc_proto_rawDescGZIP(), []int{9} -} - -func (x *CriuRestoreResp) GetPid() int32 { - if x != nil && x.Pid != nil { - return *x.Pid - } - return 0 -} - -type CriuNotify struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Script *string `protobuf:"bytes,1,opt,name=script" json:"script,omitempty"` - Pid *int32 `protobuf:"varint,2,opt,name=pid" json:"pid,omitempty"` -} - -func (x *CriuNotify) Reset() { - *x = CriuNotify{} - if protoimpl.UnsafeEnabled { - mi := &file_rpc_rpc_proto_msgTypes[10] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *CriuNotify) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*CriuNotify) ProtoMessage() {} - -func (x *CriuNotify) ProtoReflect() protoreflect.Message { - mi := &file_rpc_rpc_proto_msgTypes[10] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use CriuNotify.ProtoReflect.Descriptor instead. -func (*CriuNotify) Descriptor() ([]byte, []int) { - return file_rpc_rpc_proto_rawDescGZIP(), []int{10} -} - -func (x *CriuNotify) GetScript() string { - if x != nil && x.Script != nil { - return *x.Script - } - return "" -} - -func (x *CriuNotify) GetPid() int32 { - if x != nil && x.Pid != nil { - return *x.Pid - } - return 0 -} - -// -// List of features which can queried via -// CRIU_REQ_TYPE__FEATURE_CHECK -type CriuFeatures struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - MemTrack *bool `protobuf:"varint,1,opt,name=mem_track,json=memTrack" json:"mem_track,omitempty"` - LazyPages *bool `protobuf:"varint,2,opt,name=lazy_pages,json=lazyPages" json:"lazy_pages,omitempty"` - PidfdStore *bool `protobuf:"varint,3,opt,name=pidfd_store,json=pidfdStore" json:"pidfd_store,omitempty"` -} - -func (x *CriuFeatures) Reset() { - *x = CriuFeatures{} - if protoimpl.UnsafeEnabled { - mi := &file_rpc_rpc_proto_msgTypes[11] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *CriuFeatures) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*CriuFeatures) ProtoMessage() {} - -func (x *CriuFeatures) ProtoReflect() protoreflect.Message { - mi := &file_rpc_rpc_proto_msgTypes[11] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use CriuFeatures.ProtoReflect.Descriptor instead. -func (*CriuFeatures) Descriptor() ([]byte, []int) { - return file_rpc_rpc_proto_rawDescGZIP(), []int{11} -} - -func (x *CriuFeatures) GetMemTrack() bool { - if x != nil && x.MemTrack != nil { - return *x.MemTrack - } - return false -} - -func (x *CriuFeatures) GetLazyPages() bool { - if x != nil && x.LazyPages != nil { - return *x.LazyPages - } - return false -} - -func (x *CriuFeatures) GetPidfdStore() bool { - if x != nil && x.PidfdStore != nil { - return *x.PidfdStore - } - return false -} - -type CriuReq struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Type *CriuReqType `protobuf:"varint,1,req,name=type,enum=CriuReqType" json:"type,omitempty"` - Opts *CriuOpts `protobuf:"bytes,2,opt,name=opts" json:"opts,omitempty"` - NotifySuccess *bool `protobuf:"varint,3,opt,name=notify_success,json=notifySuccess" json:"notify_success,omitempty"` - // - // When set service won't close the connection but - // will wait for more req-s to appear. Works not - // for all request types. - KeepOpen *bool `protobuf:"varint,4,opt,name=keep_open,json=keepOpen" json:"keep_open,omitempty"` - // - // 'features' can be used to query which features - // are supported by the installed criu/kernel - // via RPC. - Features *CriuFeatures `protobuf:"bytes,5,opt,name=features" json:"features,omitempty"` - // 'pid' is used for WAIT_PID - Pid *uint32 `protobuf:"varint,6,opt,name=pid" json:"pid,omitempty"` -} - -func (x *CriuReq) Reset() { - *x = CriuReq{} - if protoimpl.UnsafeEnabled { - mi := &file_rpc_rpc_proto_msgTypes[12] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *CriuReq) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*CriuReq) ProtoMessage() {} - -func (x *CriuReq) ProtoReflect() protoreflect.Message { - mi := &file_rpc_rpc_proto_msgTypes[12] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use CriuReq.ProtoReflect.Descriptor instead. -func (*CriuReq) Descriptor() ([]byte, []int) { - return file_rpc_rpc_proto_rawDescGZIP(), []int{12} -} - -func (x *CriuReq) GetType() CriuReqType { - if x != nil && x.Type != nil { - return *x.Type - } - return CriuReqType_EMPTY -} - -func (x *CriuReq) GetOpts() *CriuOpts { - if x != nil { - return x.Opts - } - return nil -} - -func (x *CriuReq) GetNotifySuccess() bool { - if x != nil && x.NotifySuccess != nil { - return *x.NotifySuccess - } - return false -} - -func (x *CriuReq) GetKeepOpen() bool { - if x != nil && x.KeepOpen != nil { - return *x.KeepOpen - } - return false -} - -func (x *CriuReq) GetFeatures() *CriuFeatures { - if x != nil { - return x.Features - } - return nil -} - -func (x *CriuReq) GetPid() uint32 { - if x != nil && x.Pid != nil { - return *x.Pid - } - return 0 -} - -type CriuResp struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Type *CriuReqType `protobuf:"varint,1,req,name=type,enum=CriuReqType" json:"type,omitempty"` - Success *bool `protobuf:"varint,2,req,name=success" json:"success,omitempty"` - Dump *CriuDumpResp `protobuf:"bytes,3,opt,name=dump" json:"dump,omitempty"` - Restore *CriuRestoreResp `protobuf:"bytes,4,opt,name=restore" json:"restore,omitempty"` - Notify *CriuNotify `protobuf:"bytes,5,opt,name=notify" json:"notify,omitempty"` - Ps *CriuPageServerInfo `protobuf:"bytes,6,opt,name=ps" json:"ps,omitempty"` - CrErrno *int32 `protobuf:"varint,7,opt,name=cr_errno,json=crErrno" json:"cr_errno,omitempty"` - Features *CriuFeatures `protobuf:"bytes,8,opt,name=features" json:"features,omitempty"` - CrErrmsg *string `protobuf:"bytes,9,opt,name=cr_errmsg,json=crErrmsg" json:"cr_errmsg,omitempty"` - Version *CriuVersion `protobuf:"bytes,10,opt,name=version" json:"version,omitempty"` - Status *int32 `protobuf:"varint,11,opt,name=status" json:"status,omitempty"` -} - -func (x *CriuResp) Reset() { - *x = CriuResp{} - if protoimpl.UnsafeEnabled { - mi := &file_rpc_rpc_proto_msgTypes[13] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *CriuResp) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*CriuResp) ProtoMessage() {} - -func (x *CriuResp) ProtoReflect() protoreflect.Message { - mi := &file_rpc_rpc_proto_msgTypes[13] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use CriuResp.ProtoReflect.Descriptor instead. -func (*CriuResp) Descriptor() ([]byte, []int) { - return file_rpc_rpc_proto_rawDescGZIP(), []int{13} -} - -func (x *CriuResp) GetType() CriuReqType { - if x != nil && x.Type != nil { - return *x.Type - } - return CriuReqType_EMPTY -} - -func (x *CriuResp) GetSuccess() bool { - if x != nil && x.Success != nil { - return *x.Success - } - return false -} - -func (x *CriuResp) GetDump() *CriuDumpResp { - if x != nil { - return x.Dump - } - return nil -} - -func (x *CriuResp) GetRestore() *CriuRestoreResp { - if x != nil { - return x.Restore - } - return nil -} - -func (x *CriuResp) GetNotify() *CriuNotify { - if x != nil { - return x.Notify - } - return nil -} - -func (x *CriuResp) GetPs() *CriuPageServerInfo { - if x != nil { - return x.Ps - } - return nil -} - -func (x *CriuResp) GetCrErrno() int32 { - if x != nil && x.CrErrno != nil { - return *x.CrErrno - } - return 0 -} - -func (x *CriuResp) GetFeatures() *CriuFeatures { - if x != nil { - return x.Features - } - return nil -} - -func (x *CriuResp) GetCrErrmsg() string { - if x != nil && x.CrErrmsg != nil { - return *x.CrErrmsg - } - return "" -} - -func (x *CriuResp) GetVersion() *CriuVersion { - if x != nil { - return x.Version - } - return nil -} - -func (x *CriuResp) GetStatus() int32 { - if x != nil && x.Status != nil { - return *x.Status - } - return 0 -} - -// Answer for criu_req_type.VERSION requests -type CriuVersion struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - MajorNumber *int32 `protobuf:"varint,1,req,name=major_number,json=majorNumber" json:"major_number,omitempty"` - MinorNumber *int32 `protobuf:"varint,2,req,name=minor_number,json=minorNumber" json:"minor_number,omitempty"` - Gitid *string `protobuf:"bytes,3,opt,name=gitid" json:"gitid,omitempty"` - Sublevel *int32 `protobuf:"varint,4,opt,name=sublevel" json:"sublevel,omitempty"` - Extra *int32 `protobuf:"varint,5,opt,name=extra" json:"extra,omitempty"` - Name *string `protobuf:"bytes,6,opt,name=name" json:"name,omitempty"` -} - -func (x *CriuVersion) Reset() { - *x = CriuVersion{} - if protoimpl.UnsafeEnabled { - mi := &file_rpc_rpc_proto_msgTypes[14] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *CriuVersion) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*CriuVersion) ProtoMessage() {} - -func (x *CriuVersion) ProtoReflect() protoreflect.Message { - mi := &file_rpc_rpc_proto_msgTypes[14] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use CriuVersion.ProtoReflect.Descriptor instead. -func (*CriuVersion) Descriptor() ([]byte, []int) { - return file_rpc_rpc_proto_rawDescGZIP(), []int{14} -} - -func (x *CriuVersion) GetMajorNumber() int32 { - if x != nil && x.MajorNumber != nil { - return *x.MajorNumber - } - return 0 -} - -func (x *CriuVersion) GetMinorNumber() int32 { - if x != nil && x.MinorNumber != nil { - return *x.MinorNumber - } - return 0 -} - -func (x *CriuVersion) GetGitid() string { - if x != nil && x.Gitid != nil { - return *x.Gitid - } - return "" -} - -func (x *CriuVersion) GetSublevel() int32 { - if x != nil && x.Sublevel != nil { - return *x.Sublevel - } - return 0 -} - -func (x *CriuVersion) GetExtra() int32 { - if x != nil && x.Extra != nil { - return *x.Extra - } - return 0 -} - -func (x *CriuVersion) GetName() string { - if x != nil && x.Name != nil { - return *x.Name - } - return "" -} - -var File_rpc_rpc_proto protoreflect.FileDescriptor - -var file_rpc_rpc_proto_rawDesc = []byte{ - 0x0a, 0x0d, 0x72, 0x70, 0x63, 0x2f, 0x72, 0x70, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, - 0x67, 0x0a, 0x15, 0x63, 0x72, 0x69, 0x75, 0x5f, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x73, 0x65, 0x72, - 0x76, 0x65, 0x72, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, - 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, - 0x73, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, - 0x52, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x70, 0x69, 0x64, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x05, 0x52, 0x03, 0x70, 0x69, 0x64, 0x12, 0x0e, 0x0a, 0x02, 0x66, 0x64, 0x18, 0x04, - 0x20, 0x01, 0x28, 0x05, 0x52, 0x02, 0x66, 0x64, 0x22, 0x3c, 0x0a, 0x0e, 0x63, 0x72, 0x69, 0x75, - 0x5f, 0x76, 0x65, 0x74, 0x68, 0x5f, 0x70, 0x61, 0x69, 0x72, 0x12, 0x13, 0x0a, 0x05, 0x69, 0x66, - 0x5f, 0x69, 0x6e, 0x18, 0x01, 0x20, 0x02, 0x28, 0x09, 0x52, 0x04, 0x69, 0x66, 0x49, 0x6e, 0x12, - 0x15, 0x0a, 0x06, 0x69, 0x66, 0x5f, 0x6f, 0x75, 0x74, 0x18, 0x02, 0x20, 0x02, 0x28, 0x09, 0x52, - 0x05, 0x69, 0x66, 0x4f, 0x75, 0x74, 0x22, 0x33, 0x0a, 0x0d, 0x65, 0x78, 0x74, 0x5f, 0x6d, 0x6f, - 0x75, 0x6e, 0x74, 0x5f, 0x6d, 0x61, 0x70, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, - 0x20, 0x02, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x76, 0x61, 0x6c, - 0x18, 0x02, 0x20, 0x02, 0x28, 0x09, 0x52, 0x03, 0x76, 0x61, 0x6c, 0x22, 0x56, 0x0a, 0x0e, 0x6a, - 0x6f, 0x69, 0x6e, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x0e, 0x0a, - 0x02, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x02, 0x28, 0x09, 0x52, 0x02, 0x6e, 0x73, 0x12, 0x17, 0x0a, - 0x07, 0x6e, 0x73, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x02, 0x28, 0x09, 0x52, 0x06, - 0x6e, 0x73, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x65, 0x78, 0x74, 0x72, 0x61, 0x5f, - 0x6f, 0x70, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x65, 0x78, 0x74, 0x72, 0x61, - 0x4f, 0x70, 0x74, 0x22, 0x2e, 0x0a, 0x0a, 0x69, 0x6e, 0x68, 0x65, 0x72, 0x69, 0x74, 0x5f, 0x66, - 0x64, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x02, 0x28, 0x09, 0x52, 0x03, - 0x6b, 0x65, 0x79, 0x12, 0x0e, 0x0a, 0x02, 0x66, 0x64, 0x18, 0x02, 0x20, 0x02, 0x28, 0x05, 0x52, - 0x02, 0x66, 0x64, 0x22, 0x35, 0x0a, 0x0b, 0x63, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x72, 0x6f, - 0x6f, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x74, 0x72, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x04, 0x63, 0x74, 0x72, 0x6c, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, - 0x20, 0x02, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x22, 0x1f, 0x0a, 0x07, 0x75, 0x6e, - 0x69, 0x78, 0x5f, 0x73, 0x6b, 0x12, 0x14, 0x0a, 0x05, 0x69, 0x6e, 0x6f, 0x64, 0x65, 0x18, 0x01, - 0x20, 0x02, 0x28, 0x0d, 0x52, 0x05, 0x69, 0x6e, 0x6f, 0x64, 0x65, 0x22, 0x8c, 0x11, 0x0a, 0x09, - 0x63, 0x72, 0x69, 0x75, 0x5f, 0x6f, 0x70, 0x74, 0x73, 0x12, 0x22, 0x0a, 0x0d, 0x69, 0x6d, 0x61, - 0x67, 0x65, 0x73, 0x5f, 0x64, 0x69, 0x72, 0x5f, 0x66, 0x64, 0x18, 0x01, 0x20, 0x02, 0x28, 0x05, - 0x52, 0x0b, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x73, 0x44, 0x69, 0x72, 0x46, 0x64, 0x12, 0x10, 0x0a, - 0x03, 0x70, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x70, 0x69, 0x64, 0x12, - 0x23, 0x0a, 0x0d, 0x6c, 0x65, 0x61, 0x76, 0x65, 0x5f, 0x72, 0x75, 0x6e, 0x6e, 0x69, 0x6e, 0x67, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x6c, 0x65, 0x61, 0x76, 0x65, 0x52, 0x75, 0x6e, - 0x6e, 0x69, 0x6e, 0x67, 0x12, 0x1e, 0x0a, 0x0b, 0x65, 0x78, 0x74, 0x5f, 0x75, 0x6e, 0x69, 0x78, - 0x5f, 0x73, 0x6b, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x65, 0x78, 0x74, 0x55, 0x6e, - 0x69, 0x78, 0x53, 0x6b, 0x12, 0x27, 0x0a, 0x0f, 0x74, 0x63, 0x70, 0x5f, 0x65, 0x73, 0x74, 0x61, - 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x74, - 0x63, 0x70, 0x45, 0x73, 0x74, 0x61, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x64, 0x12, 0x27, 0x0a, - 0x0f, 0x65, 0x76, 0x61, 0x73, 0x69, 0x76, 0x65, 0x5f, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, - 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x65, 0x76, 0x61, 0x73, 0x69, 0x76, 0x65, 0x44, - 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x73, 0x68, 0x65, 0x6c, 0x6c, 0x5f, - 0x6a, 0x6f, 0x62, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x73, 0x68, 0x65, 0x6c, 0x6c, - 0x4a, 0x6f, 0x62, 0x12, 0x1d, 0x0a, 0x0a, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x6c, 0x6f, 0x63, 0x6b, - 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x66, 0x69, 0x6c, 0x65, 0x4c, 0x6f, 0x63, - 0x6b, 0x73, 0x12, 0x1e, 0x0a, 0x09, 0x6c, 0x6f, 0x67, 0x5f, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x18, - 0x09, 0x20, 0x01, 0x28, 0x05, 0x3a, 0x01, 0x32, 0x52, 0x08, 0x6c, 0x6f, 0x67, 0x4c, 0x65, 0x76, - 0x65, 0x6c, 0x12, 0x19, 0x0a, 0x08, 0x6c, 0x6f, 0x67, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x0a, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6c, 0x6f, 0x67, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x26, 0x0a, - 0x02, 0x70, 0x73, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x63, 0x72, 0x69, 0x75, - 0x5f, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x69, 0x6e, 0x66, - 0x6f, 0x52, 0x02, 0x70, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x5f, - 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x73, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x6e, - 0x6f, 0x74, 0x69, 0x66, 0x79, 0x53, 0x63, 0x72, 0x69, 0x70, 0x74, 0x73, 0x12, 0x12, 0x0a, 0x04, - 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x72, 0x6f, 0x6f, 0x74, - 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x6d, 0x67, 0x18, 0x0e, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x49, 0x6d, 0x67, 0x12, - 0x1b, 0x0a, 0x09, 0x74, 0x72, 0x61, 0x63, 0x6b, 0x5f, 0x6d, 0x65, 0x6d, 0x18, 0x0f, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x08, 0x74, 0x72, 0x61, 0x63, 0x6b, 0x4d, 0x65, 0x6d, 0x12, 0x1d, 0x0a, 0x0a, - 0x61, 0x75, 0x74, 0x6f, 0x5f, 0x64, 0x65, 0x64, 0x75, 0x70, 0x18, 0x10, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x09, 0x61, 0x75, 0x74, 0x6f, 0x44, 0x65, 0x64, 0x75, 0x70, 0x12, 0x1e, 0x0a, 0x0b, 0x77, - 0x6f, 0x72, 0x6b, 0x5f, 0x64, 0x69, 0x72, 0x5f, 0x66, 0x64, 0x18, 0x11, 0x20, 0x01, 0x28, 0x05, - 0x52, 0x09, 0x77, 0x6f, 0x72, 0x6b, 0x44, 0x69, 0x72, 0x46, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x6c, - 0x69, 0x6e, 0x6b, 0x5f, 0x72, 0x65, 0x6d, 0x61, 0x70, 0x18, 0x12, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x09, 0x6c, 0x69, 0x6e, 0x6b, 0x52, 0x65, 0x6d, 0x61, 0x70, 0x12, 0x25, 0x0a, 0x05, 0x76, 0x65, - 0x74, 0x68, 0x73, 0x18, 0x13, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x63, 0x72, 0x69, 0x75, - 0x5f, 0x76, 0x65, 0x74, 0x68, 0x5f, 0x70, 0x61, 0x69, 0x72, 0x52, 0x05, 0x76, 0x65, 0x74, 0x68, - 0x73, 0x12, 0x23, 0x0a, 0x07, 0x63, 0x70, 0x75, 0x5f, 0x63, 0x61, 0x70, 0x18, 0x14, 0x20, 0x01, - 0x28, 0x0d, 0x3a, 0x0a, 0x34, 0x32, 0x39, 0x34, 0x39, 0x36, 0x37, 0x32, 0x39, 0x35, 0x52, 0x06, - 0x63, 0x70, 0x75, 0x43, 0x61, 0x70, 0x12, 0x1f, 0x0a, 0x0b, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x5f, - 0x69, 0x72, 0x6d, 0x61, 0x70, 0x18, 0x15, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x66, 0x6f, 0x72, - 0x63, 0x65, 0x49, 0x72, 0x6d, 0x61, 0x70, 0x12, 0x19, 0x0a, 0x08, 0x65, 0x78, 0x65, 0x63, 0x5f, - 0x63, 0x6d, 0x64, 0x18, 0x16, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x65, 0x78, 0x65, 0x63, 0x43, - 0x6d, 0x64, 0x12, 0x27, 0x0a, 0x07, 0x65, 0x78, 0x74, 0x5f, 0x6d, 0x6e, 0x74, 0x18, 0x17, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x65, 0x78, 0x74, 0x5f, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x5f, - 0x6d, 0x61, 0x70, 0x52, 0x06, 0x65, 0x78, 0x74, 0x4d, 0x6e, 0x74, 0x12, 0x25, 0x0a, 0x0e, 0x6d, - 0x61, 0x6e, 0x61, 0x67, 0x65, 0x5f, 0x63, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x18, 0x18, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x0d, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x43, 0x67, 0x72, 0x6f, 0x75, - 0x70, 0x73, 0x12, 0x25, 0x0a, 0x07, 0x63, 0x67, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x19, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x63, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x72, 0x6f, 0x6f, - 0x74, 0x52, 0x06, 0x63, 0x67, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x73, 0x74, - 0x5f, 0x73, 0x69, 0x62, 0x6c, 0x69, 0x6e, 0x67, 0x18, 0x1a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, - 0x72, 0x73, 0x74, 0x53, 0x69, 0x62, 0x6c, 0x69, 0x6e, 0x67, 0x12, 0x2a, 0x0a, 0x0a, 0x69, 0x6e, - 0x68, 0x65, 0x72, 0x69, 0x74, 0x5f, 0x66, 0x64, 0x18, 0x1b, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0b, - 0x2e, 0x69, 0x6e, 0x68, 0x65, 0x72, 0x69, 0x74, 0x5f, 0x66, 0x64, 0x52, 0x09, 0x69, 0x6e, 0x68, - 0x65, 0x72, 0x69, 0x74, 0x46, 0x64, 0x12, 0x20, 0x0a, 0x0c, 0x61, 0x75, 0x74, 0x6f, 0x5f, 0x65, - 0x78, 0x74, 0x5f, 0x6d, 0x6e, 0x74, 0x18, 0x1c, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x61, 0x75, - 0x74, 0x6f, 0x45, 0x78, 0x74, 0x4d, 0x6e, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x65, 0x78, 0x74, 0x5f, - 0x73, 0x68, 0x61, 0x72, 0x69, 0x6e, 0x67, 0x18, 0x1d, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x65, - 0x78, 0x74, 0x53, 0x68, 0x61, 0x72, 0x69, 0x6e, 0x67, 0x12, 0x1f, 0x0a, 0x0b, 0x65, 0x78, 0x74, - 0x5f, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x73, 0x18, 0x1e, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, - 0x65, 0x78, 0x74, 0x4d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x73, 0x6b, - 0x69, 0x70, 0x5f, 0x6d, 0x6e, 0x74, 0x18, 0x1f, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x73, 0x6b, - 0x69, 0x70, 0x4d, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x5f, - 0x66, 0x73, 0x18, 0x20, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, - 0x46, 0x73, 0x12, 0x28, 0x0a, 0x0b, 0x75, 0x6e, 0x69, 0x78, 0x5f, 0x73, 0x6b, 0x5f, 0x69, 0x6e, - 0x6f, 0x18, 0x21, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x08, 0x2e, 0x75, 0x6e, 0x69, 0x78, 0x5f, 0x73, - 0x6b, 0x52, 0x09, 0x75, 0x6e, 0x69, 0x78, 0x53, 0x6b, 0x49, 0x6e, 0x6f, 0x12, 0x3d, 0x0a, 0x13, - 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x5f, 0x63, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x5f, 0x6d, - 0x6f, 0x64, 0x65, 0x18, 0x22, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0d, 0x2e, 0x63, 0x72, 0x69, 0x75, - 0x5f, 0x63, 0x67, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x52, 0x11, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, - 0x43, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x28, 0x0a, 0x0b, 0x67, - 0x68, 0x6f, 0x73, 0x74, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x23, 0x20, 0x01, 0x28, 0x0d, - 0x3a, 0x07, 0x31, 0x30, 0x34, 0x38, 0x35, 0x37, 0x36, 0x52, 0x0a, 0x67, 0x68, 0x6f, 0x73, 0x74, - 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x28, 0x0a, 0x10, 0x69, 0x72, 0x6d, 0x61, 0x70, 0x5f, 0x73, - 0x63, 0x61, 0x6e, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x73, 0x18, 0x24, 0x20, 0x03, 0x28, 0x09, 0x52, - 0x0e, 0x69, 0x72, 0x6d, 0x61, 0x70, 0x53, 0x63, 0x61, 0x6e, 0x50, 0x61, 0x74, 0x68, 0x73, 0x12, - 0x1a, 0x0a, 0x08, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x18, 0x25, 0x20, 0x03, 0x28, - 0x09, 0x52, 0x08, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x12, 0x19, 0x0a, 0x08, 0x65, - 0x6d, 0x70, 0x74, 0x79, 0x5f, 0x6e, 0x73, 0x18, 0x26, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x65, - 0x6d, 0x70, 0x74, 0x79, 0x4e, 0x73, 0x12, 0x28, 0x0a, 0x07, 0x6a, 0x6f, 0x69, 0x6e, 0x5f, 0x6e, - 0x73, 0x18, 0x27, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x6a, 0x6f, 0x69, 0x6e, 0x5f, 0x6e, - 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x06, 0x6a, 0x6f, 0x69, 0x6e, 0x4e, 0x73, - 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x70, 0x72, 0x6f, 0x70, 0x73, - 0x18, 0x29, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x50, 0x72, - 0x6f, 0x70, 0x73, 0x12, 0x2a, 0x0a, 0x11, 0x63, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x70, 0x72, - 0x6f, 0x70, 0x73, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x2a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, - 0x63, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x50, 0x72, 0x6f, 0x70, 0x73, 0x46, 0x69, 0x6c, 0x65, 0x12, - 0x34, 0x0a, 0x16, 0x63, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x64, 0x75, 0x6d, 0x70, 0x5f, 0x63, - 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x18, 0x2b, 0x20, 0x03, 0x28, 0x09, 0x52, - 0x14, 0x63, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x44, 0x75, 0x6d, 0x70, 0x43, 0x6f, 0x6e, 0x74, 0x72, - 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x12, 0x23, 0x0a, 0x0d, 0x66, 0x72, 0x65, 0x65, 0x7a, 0x65, 0x5f, - 0x63, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x18, 0x2c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x66, 0x72, - 0x65, 0x65, 0x7a, 0x65, 0x43, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x18, 0x0a, 0x07, 0x74, 0x69, - 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x2d, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x74, 0x69, 0x6d, - 0x65, 0x6f, 0x75, 0x74, 0x12, 0x2b, 0x0a, 0x12, 0x74, 0x63, 0x70, 0x5f, 0x73, 0x6b, 0x69, 0x70, - 0x5f, 0x69, 0x6e, 0x5f, 0x66, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x18, 0x2e, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x0f, 0x74, 0x63, 0x70, 0x53, 0x6b, 0x69, 0x70, 0x49, 0x6e, 0x46, 0x6c, 0x69, 0x67, 0x68, - 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x77, 0x65, 0x61, 0x6b, 0x5f, 0x73, 0x79, 0x73, 0x63, 0x74, 0x6c, - 0x73, 0x18, 0x2f, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x77, 0x65, 0x61, 0x6b, 0x53, 0x79, 0x73, - 0x63, 0x74, 0x6c, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x6c, 0x61, 0x7a, 0x79, 0x5f, 0x70, 0x61, 0x67, - 0x65, 0x73, 0x18, 0x30, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x6c, 0x61, 0x7a, 0x79, 0x50, 0x61, - 0x67, 0x65, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x5f, 0x66, 0x64, - 0x18, 0x31, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x46, 0x64, - 0x12, 0x2a, 0x0a, 0x11, 0x6f, 0x72, 0x70, 0x68, 0x61, 0x6e, 0x5f, 0x70, 0x74, 0x73, 0x5f, 0x6d, - 0x61, 0x73, 0x74, 0x65, 0x72, 0x18, 0x32, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x6f, 0x72, 0x70, - 0x68, 0x61, 0x6e, 0x50, 0x74, 0x73, 0x4d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x12, 0x1f, 0x0a, 0x0b, - 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x33, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x1b, 0x0a, - 0x09, 0x74, 0x63, 0x70, 0x5f, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x18, 0x34, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x08, 0x74, 0x63, 0x70, 0x43, 0x6c, 0x6f, 0x73, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x6c, 0x73, - 0x6d, 0x5f, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x35, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0a, 0x6c, 0x73, 0x6d, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x74, - 0x6c, 0x73, 0x5f, 0x63, 0x61, 0x63, 0x65, 0x72, 0x74, 0x18, 0x36, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x09, 0x74, 0x6c, 0x73, 0x43, 0x61, 0x63, 0x65, 0x72, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x6c, - 0x73, 0x5f, 0x63, 0x61, 0x63, 0x72, 0x6c, 0x18, 0x37, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, - 0x6c, 0x73, 0x43, 0x61, 0x63, 0x72, 0x6c, 0x12, 0x19, 0x0a, 0x08, 0x74, 0x6c, 0x73, 0x5f, 0x63, - 0x65, 0x72, 0x74, 0x18, 0x38, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x74, 0x6c, 0x73, 0x43, 0x65, - 0x72, 0x74, 0x12, 0x17, 0x0a, 0x07, 0x74, 0x6c, 0x73, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x39, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x06, 0x74, 0x6c, 0x73, 0x4b, 0x65, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x74, - 0x6c, 0x73, 0x18, 0x3a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x03, 0x74, 0x6c, 0x73, 0x12, 0x27, 0x0a, - 0x10, 0x74, 0x6c, 0x73, 0x5f, 0x6e, 0x6f, 0x5f, 0x63, 0x6e, 0x5f, 0x76, 0x65, 0x72, 0x69, 0x66, - 0x79, 0x18, 0x3b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x74, 0x6c, 0x73, 0x4e, 0x6f, 0x43, 0x6e, - 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x12, 0x1f, 0x0a, 0x0b, 0x63, 0x67, 0x72, 0x6f, 0x75, 0x70, - 0x5f, 0x79, 0x61, 0x72, 0x64, 0x18, 0x3c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x63, 0x67, 0x72, - 0x6f, 0x75, 0x70, 0x59, 0x61, 0x72, 0x64, 0x12, 0x3f, 0x0a, 0x0d, 0x70, 0x72, 0x65, 0x5f, 0x64, - 0x75, 0x6d, 0x70, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x3d, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x13, - 0x2e, 0x63, 0x72, 0x69, 0x75, 0x5f, 0x70, 0x72, 0x65, 0x5f, 0x64, 0x75, 0x6d, 0x70, 0x5f, 0x6d, - 0x6f, 0x64, 0x65, 0x3a, 0x06, 0x53, 0x50, 0x4c, 0x49, 0x43, 0x45, 0x52, 0x0b, 0x70, 0x72, 0x65, - 0x44, 0x75, 0x6d, 0x70, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x24, 0x0a, 0x0e, 0x70, 0x69, 0x64, 0x66, - 0x64, 0x5f, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x5f, 0x73, 0x6b, 0x18, 0x3e, 0x20, 0x01, 0x28, 0x05, - 0x52, 0x0c, 0x70, 0x69, 0x64, 0x66, 0x64, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x53, 0x6b, 0x12, 0x2a, - 0x0a, 0x11, 0x6c, 0x73, 0x6d, 0x5f, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x63, 0x6f, 0x6e, 0x74, - 0x65, 0x78, 0x74, 0x18, 0x3f, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x6c, 0x73, 0x6d, 0x4d, 0x6f, - 0x75, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x22, 0x2c, 0x0a, 0x0e, 0x63, 0x72, - 0x69, 0x75, 0x5f, 0x64, 0x75, 0x6d, 0x70, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x12, 0x1a, 0x0a, 0x08, - 0x72, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, - 0x72, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x64, 0x22, 0x25, 0x0a, 0x11, 0x63, 0x72, 0x69, 0x75, - 0x5f, 0x72, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x12, 0x10, 0x0a, - 0x03, 0x70, 0x69, 0x64, 0x18, 0x01, 0x20, 0x02, 0x28, 0x05, 0x52, 0x03, 0x70, 0x69, 0x64, 0x22, - 0x37, 0x0a, 0x0b, 0x63, 0x72, 0x69, 0x75, 0x5f, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x12, 0x16, - 0x0a, 0x06, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, - 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x70, 0x69, 0x64, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x05, 0x52, 0x03, 0x70, 0x69, 0x64, 0x22, 0x6c, 0x0a, 0x0d, 0x63, 0x72, 0x69, 0x75, - 0x5f, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x6d, 0x65, 0x6d, - 0x5f, 0x74, 0x72, 0x61, 0x63, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x6d, 0x65, - 0x6d, 0x54, 0x72, 0x61, 0x63, 0x6b, 0x12, 0x1d, 0x0a, 0x0a, 0x6c, 0x61, 0x7a, 0x79, 0x5f, 0x70, - 0x61, 0x67, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x6c, 0x61, 0x7a, 0x79, - 0x50, 0x61, 0x67, 0x65, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x69, 0x64, 0x66, 0x64, 0x5f, 0x73, - 0x74, 0x6f, 0x72, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x70, 0x69, 0x64, 0x66, - 0x64, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x22, 0xd0, 0x01, 0x0a, 0x08, 0x63, 0x72, 0x69, 0x75, 0x5f, - 0x72, 0x65, 0x71, 0x12, 0x22, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x02, 0x28, - 0x0e, 0x32, 0x0e, 0x2e, 0x63, 0x72, 0x69, 0x75, 0x5f, 0x72, 0x65, 0x71, 0x5f, 0x74, 0x79, 0x70, - 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x1e, 0x0a, 0x04, 0x6f, 0x70, 0x74, 0x73, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0a, 0x2e, 0x63, 0x72, 0x69, 0x75, 0x5f, 0x6f, 0x70, 0x74, - 0x73, 0x52, 0x04, 0x6f, 0x70, 0x74, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x6e, 0x6f, 0x74, 0x69, 0x66, - 0x79, 0x5f, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x0d, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x1b, - 0x0a, 0x09, 0x6b, 0x65, 0x65, 0x70, 0x5f, 0x6f, 0x70, 0x65, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x08, 0x6b, 0x65, 0x65, 0x70, 0x4f, 0x70, 0x65, 0x6e, 0x12, 0x2a, 0x0a, 0x08, 0x66, - 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, - 0x63, 0x72, 0x69, 0x75, 0x5f, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x52, 0x08, 0x66, - 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x70, 0x69, 0x64, 0x18, 0x06, - 0x20, 0x01, 0x28, 0x0d, 0x52, 0x03, 0x70, 0x69, 0x64, 0x22, 0x8f, 0x03, 0x0a, 0x09, 0x63, 0x72, - 0x69, 0x75, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x12, 0x22, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, - 0x01, 0x20, 0x02, 0x28, 0x0e, 0x32, 0x0e, 0x2e, 0x63, 0x72, 0x69, 0x75, 0x5f, 0x72, 0x65, 0x71, - 0x5f, 0x74, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, - 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x02, 0x28, 0x08, 0x52, 0x07, 0x73, 0x75, - 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x23, 0x0a, 0x04, 0x64, 0x75, 0x6d, 0x70, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x63, 0x72, 0x69, 0x75, 0x5f, 0x64, 0x75, 0x6d, 0x70, 0x5f, - 0x72, 0x65, 0x73, 0x70, 0x52, 0x04, 0x64, 0x75, 0x6d, 0x70, 0x12, 0x2c, 0x0a, 0x07, 0x72, 0x65, - 0x73, 0x74, 0x6f, 0x72, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x63, 0x72, - 0x69, 0x75, 0x5f, 0x72, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x52, - 0x07, 0x72, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x12, 0x24, 0x0a, 0x06, 0x6e, 0x6f, 0x74, 0x69, - 0x66, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x63, 0x72, 0x69, 0x75, 0x5f, - 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x52, 0x06, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x12, 0x26, - 0x0a, 0x02, 0x70, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x63, 0x72, 0x69, - 0x75, 0x5f, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x69, 0x6e, - 0x66, 0x6f, 0x52, 0x02, 0x70, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x72, 0x5f, 0x65, 0x72, 0x72, - 0x6e, 0x6f, 0x18, 0x07, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x63, 0x72, 0x45, 0x72, 0x72, 0x6e, - 0x6f, 0x12, 0x2a, 0x0a, 0x08, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x18, 0x08, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x63, 0x72, 0x69, 0x75, 0x5f, 0x66, 0x65, 0x61, 0x74, 0x75, - 0x72, 0x65, 0x73, 0x52, 0x08, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x12, 0x1b, 0x0a, - 0x09, 0x63, 0x72, 0x5f, 0x65, 0x72, 0x72, 0x6d, 0x73, 0x67, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x08, 0x63, 0x72, 0x45, 0x72, 0x72, 0x6d, 0x73, 0x67, 0x12, 0x27, 0x0a, 0x07, 0x76, 0x65, - 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x63, 0x72, - 0x69, 0x75, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, - 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x0b, 0x20, - 0x01, 0x28, 0x05, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0xb0, 0x01, 0x0a, 0x0c, - 0x63, 0x72, 0x69, 0x75, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x21, 0x0a, 0x0c, - 0x6d, 0x61, 0x6a, 0x6f, 0x72, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x01, 0x20, 0x02, - 0x28, 0x05, 0x52, 0x0b, 0x6d, 0x61, 0x6a, 0x6f, 0x72, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, - 0x21, 0x0a, 0x0c, 0x6d, 0x69, 0x6e, 0x6f, 0x72, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, - 0x02, 0x20, 0x02, 0x28, 0x05, 0x52, 0x0b, 0x6d, 0x69, 0x6e, 0x6f, 0x72, 0x4e, 0x75, 0x6d, 0x62, - 0x65, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x67, 0x69, 0x74, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x05, 0x67, 0x69, 0x74, 0x69, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x75, 0x62, 0x6c, - 0x65, 0x76, 0x65, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x73, 0x75, 0x62, 0x6c, - 0x65, 0x76, 0x65, 0x6c, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x78, 0x74, 0x72, 0x61, 0x18, 0x05, 0x20, - 0x01, 0x28, 0x05, 0x52, 0x05, 0x65, 0x78, 0x74, 0x72, 0x61, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, - 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x2a, 0x5f, - 0x0a, 0x0c, 0x63, 0x72, 0x69, 0x75, 0x5f, 0x63, 0x67, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x12, 0x0a, - 0x0a, 0x06, 0x49, 0x47, 0x4e, 0x4f, 0x52, 0x45, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x43, 0x47, - 0x5f, 0x4e, 0x4f, 0x4e, 0x45, 0x10, 0x01, 0x12, 0x09, 0x0a, 0x05, 0x50, 0x52, 0x4f, 0x50, 0x53, - 0x10, 0x02, 0x12, 0x08, 0x0a, 0x04, 0x53, 0x4f, 0x46, 0x54, 0x10, 0x03, 0x12, 0x08, 0x0a, 0x04, - 0x46, 0x55, 0x4c, 0x4c, 0x10, 0x04, 0x12, 0x0a, 0x0a, 0x06, 0x53, 0x54, 0x52, 0x49, 0x43, 0x54, - 0x10, 0x05, 0x12, 0x0b, 0x0a, 0x07, 0x44, 0x45, 0x46, 0x41, 0x55, 0x4c, 0x54, 0x10, 0x06, 0x2a, - 0x2d, 0x0a, 0x12, 0x63, 0x72, 0x69, 0x75, 0x5f, 0x70, 0x72, 0x65, 0x5f, 0x64, 0x75, 0x6d, 0x70, - 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x12, 0x0a, 0x0a, 0x06, 0x53, 0x50, 0x4c, 0x49, 0x43, 0x45, 0x10, - 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x56, 0x4d, 0x5f, 0x52, 0x45, 0x41, 0x44, 0x10, 0x02, 0x2a, 0xd0, - 0x01, 0x0a, 0x0d, 0x63, 0x72, 0x69, 0x75, 0x5f, 0x72, 0x65, 0x71, 0x5f, 0x74, 0x79, 0x70, 0x65, - 0x12, 0x09, 0x0a, 0x05, 0x45, 0x4d, 0x50, 0x54, 0x59, 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x44, - 0x55, 0x4d, 0x50, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x52, 0x45, 0x53, 0x54, 0x4f, 0x52, 0x45, - 0x10, 0x02, 0x12, 0x09, 0x0a, 0x05, 0x43, 0x48, 0x45, 0x43, 0x4b, 0x10, 0x03, 0x12, 0x0c, 0x0a, - 0x08, 0x50, 0x52, 0x45, 0x5f, 0x44, 0x55, 0x4d, 0x50, 0x10, 0x04, 0x12, 0x0f, 0x0a, 0x0b, 0x50, - 0x41, 0x47, 0x45, 0x5f, 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, 0x10, 0x05, 0x12, 0x0a, 0x0a, 0x06, - 0x4e, 0x4f, 0x54, 0x49, 0x46, 0x59, 0x10, 0x06, 0x12, 0x10, 0x0a, 0x0c, 0x43, 0x50, 0x55, 0x49, - 0x4e, 0x46, 0x4f, 0x5f, 0x44, 0x55, 0x4d, 0x50, 0x10, 0x07, 0x12, 0x11, 0x0a, 0x0d, 0x43, 0x50, - 0x55, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x43, 0x48, 0x45, 0x43, 0x4b, 0x10, 0x08, 0x12, 0x11, 0x0a, - 0x0d, 0x46, 0x45, 0x41, 0x54, 0x55, 0x52, 0x45, 0x5f, 0x43, 0x48, 0x45, 0x43, 0x4b, 0x10, 0x09, - 0x12, 0x0b, 0x0a, 0x07, 0x56, 0x45, 0x52, 0x53, 0x49, 0x4f, 0x4e, 0x10, 0x0a, 0x12, 0x0c, 0x0a, - 0x08, 0x57, 0x41, 0x49, 0x54, 0x5f, 0x50, 0x49, 0x44, 0x10, 0x0b, 0x12, 0x14, 0x0a, 0x10, 0x50, - 0x41, 0x47, 0x45, 0x5f, 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, 0x5f, 0x43, 0x48, 0x4c, 0x44, 0x10, - 0x0c, -} - -var ( - file_rpc_rpc_proto_rawDescOnce sync.Once - file_rpc_rpc_proto_rawDescData = file_rpc_rpc_proto_rawDesc -) - -func file_rpc_rpc_proto_rawDescGZIP() []byte { - file_rpc_rpc_proto_rawDescOnce.Do(func() { - file_rpc_rpc_proto_rawDescData = protoimpl.X.CompressGZIP(file_rpc_rpc_proto_rawDescData) - }) - return file_rpc_rpc_proto_rawDescData -} - -var file_rpc_rpc_proto_enumTypes = make([]protoimpl.EnumInfo, 3) -var file_rpc_rpc_proto_msgTypes = make([]protoimpl.MessageInfo, 15) -var file_rpc_rpc_proto_goTypes = []interface{}{ - (CriuCgMode)(0), // 0: criu_cg_mode - (CriuPreDumpMode)(0), // 1: criu_pre_dump_mode - (CriuReqType)(0), // 2: criu_req_type - (*CriuPageServerInfo)(nil), // 3: criu_page_server_info - (*CriuVethPair)(nil), // 4: criu_veth_pair - (*ExtMountMap)(nil), // 5: ext_mount_map - (*JoinNamespace)(nil), // 6: join_namespace - (*InheritFd)(nil), // 7: inherit_fd - (*CgroupRoot)(nil), // 8: cgroup_root - (*UnixSk)(nil), // 9: unix_sk - (*CriuOpts)(nil), // 10: criu_opts - (*CriuDumpResp)(nil), // 11: criu_dump_resp - (*CriuRestoreResp)(nil), // 12: criu_restore_resp - (*CriuNotify)(nil), // 13: criu_notify - (*CriuFeatures)(nil), // 14: criu_features - (*CriuReq)(nil), // 15: criu_req - (*CriuResp)(nil), // 16: criu_resp - (*CriuVersion)(nil), // 17: criu_version -} -var file_rpc_rpc_proto_depIdxs = []int32{ - 3, // 0: criu_opts.ps:type_name -> criu_page_server_info - 4, // 1: criu_opts.veths:type_name -> criu_veth_pair - 5, // 2: criu_opts.ext_mnt:type_name -> ext_mount_map - 8, // 3: criu_opts.cg_root:type_name -> cgroup_root - 7, // 4: criu_opts.inherit_fd:type_name -> inherit_fd - 9, // 5: criu_opts.unix_sk_ino:type_name -> unix_sk - 0, // 6: criu_opts.manage_cgroups_mode:type_name -> criu_cg_mode - 6, // 7: criu_opts.join_ns:type_name -> join_namespace - 1, // 8: criu_opts.pre_dump_mode:type_name -> criu_pre_dump_mode - 2, // 9: criu_req.type:type_name -> criu_req_type - 10, // 10: criu_req.opts:type_name -> criu_opts - 14, // 11: criu_req.features:type_name -> criu_features - 2, // 12: criu_resp.type:type_name -> criu_req_type - 11, // 13: criu_resp.dump:type_name -> criu_dump_resp - 12, // 14: criu_resp.restore:type_name -> criu_restore_resp - 13, // 15: criu_resp.notify:type_name -> criu_notify - 3, // 16: criu_resp.ps:type_name -> criu_page_server_info - 14, // 17: criu_resp.features:type_name -> criu_features - 17, // 18: criu_resp.version:type_name -> criu_version - 19, // [19:19] is the sub-list for method output_type - 19, // [19:19] is the sub-list for method input_type - 19, // [19:19] is the sub-list for extension type_name - 19, // [19:19] is the sub-list for extension extendee - 0, // [0:19] is the sub-list for field type_name -} - -func init() { file_rpc_rpc_proto_init() } -func file_rpc_rpc_proto_init() { - if File_rpc_rpc_proto != nil { - return - } - if !protoimpl.UnsafeEnabled { - file_rpc_rpc_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CriuPageServerInfo); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_rpc_rpc_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CriuVethPair); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_rpc_rpc_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ExtMountMap); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_rpc_rpc_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*JoinNamespace); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_rpc_rpc_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*InheritFd); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_rpc_rpc_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CgroupRoot); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_rpc_rpc_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UnixSk); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_rpc_rpc_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CriuOpts); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_rpc_rpc_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CriuDumpResp); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_rpc_rpc_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CriuRestoreResp); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_rpc_rpc_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CriuNotify); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_rpc_rpc_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CriuFeatures); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_rpc_rpc_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CriuReq); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_rpc_rpc_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CriuResp); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_rpc_rpc_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CriuVersion); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_rpc_rpc_proto_rawDesc, - NumEnums: 3, - NumMessages: 15, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_rpc_rpc_proto_goTypes, - DependencyIndexes: file_rpc_rpc_proto_depIdxs, - EnumInfos: file_rpc_rpc_proto_enumTypes, - MessageInfos: file_rpc_rpc_proto_msgTypes, - }.Build() - File_rpc_rpc_proto = out.File - file_rpc_rpc_proto_rawDesc = nil - file_rpc_rpc_proto_goTypes = nil - file_rpc_rpc_proto_depIdxs = nil -} diff --git a/vendor/github.com/checkpoint-restore/go-criu/v5/rpc/rpc.proto b/vendor/github.com/checkpoint-restore/go-criu/v5/rpc/rpc.proto deleted file mode 100644 index 61e1b24f4a4..00000000000 --- a/vendor/github.com/checkpoint-restore/go-criu/v5/rpc/rpc.proto +++ /dev/null @@ -1,239 +0,0 @@ -// SPDX-License-Identifier: MIT - -syntax = "proto2"; - -message criu_page_server_info { - optional string address = 1; - optional int32 port = 2; - optional int32 pid = 3; - optional int32 fd = 4; -} - -message criu_veth_pair { - required string if_in = 1; - required string if_out = 2; -}; - -message ext_mount_map { - required string key = 1; - required string val = 2; -}; - -message join_namespace { - required string ns = 1; - required string ns_file = 2; - optional string extra_opt = 3; -} - -message inherit_fd { - required string key = 1; - required int32 fd = 2; -}; - -message cgroup_root { - optional string ctrl = 1; - required string path = 2; -}; - -message unix_sk { - required uint32 inode = 1; -}; - -enum criu_cg_mode { - IGNORE = 0; - CG_NONE = 1; - PROPS = 2; - SOFT = 3; - FULL = 4; - STRICT = 5; - DEFAULT = 6; -}; - -enum criu_pre_dump_mode { - SPLICE = 1; - VM_READ = 2; -}; - -message criu_opts { - required int32 images_dir_fd = 1; - optional int32 pid = 2; /* if not set on dump, will dump requesting process */ - - optional bool leave_running = 3; - optional bool ext_unix_sk = 4; - optional bool tcp_established = 5; - optional bool evasive_devices = 6; - optional bool shell_job = 7; - optional bool file_locks = 8; - optional int32 log_level = 9 [default = 2]; - optional string log_file = 10; /* No subdirs are allowed. Consider using work-dir */ - - optional criu_page_server_info ps = 11; - - optional bool notify_scripts = 12; - - optional string root = 13; - optional string parent_img = 14; - optional bool track_mem = 15; - optional bool auto_dedup = 16; - - optional int32 work_dir_fd = 17; - optional bool link_remap = 18; - repeated criu_veth_pair veths = 19; /* DEPRECATED, use external instead */ - - optional uint32 cpu_cap = 20 [default = 0xffffffff]; - optional bool force_irmap = 21; - repeated string exec_cmd = 22; - - repeated ext_mount_map ext_mnt = 23; /* DEPRECATED, use external instead */ - optional bool manage_cgroups = 24; /* backward compatibility */ - repeated cgroup_root cg_root = 25; - - optional bool rst_sibling = 26; /* swrk only */ - repeated inherit_fd inherit_fd = 27; /* swrk only */ - - optional bool auto_ext_mnt = 28; - optional bool ext_sharing = 29; - optional bool ext_masters = 30; - - repeated string skip_mnt = 31; - repeated string enable_fs = 32; - - repeated unix_sk unix_sk_ino = 33; /* DEPRECATED, use external instead */ - - optional criu_cg_mode manage_cgroups_mode = 34; - optional uint32 ghost_limit = 35 [default = 0x100000]; - repeated string irmap_scan_paths = 36; - repeated string external = 37; - optional uint32 empty_ns = 38; - repeated join_namespace join_ns = 39; - - optional string cgroup_props = 41; - optional string cgroup_props_file = 42; - repeated string cgroup_dump_controller = 43; - - optional string freeze_cgroup = 44; - optional uint32 timeout = 45; - optional bool tcp_skip_in_flight = 46; - optional bool weak_sysctls = 47; - optional bool lazy_pages = 48; - optional int32 status_fd = 49; - optional bool orphan_pts_master = 50; - optional string config_file = 51; - optional bool tcp_close = 52; - optional string lsm_profile = 53; - optional string tls_cacert = 54; - optional string tls_cacrl = 55; - optional string tls_cert = 56; - optional string tls_key = 57; - optional bool tls = 58; - optional bool tls_no_cn_verify = 59; - optional string cgroup_yard = 60; - optional criu_pre_dump_mode pre_dump_mode = 61 [default = SPLICE]; - optional int32 pidfd_store_sk = 62; - optional string lsm_mount_context = 63; -/* optional bool check_mounts = 128; */ -} - -message criu_dump_resp { - optional bool restored = 1; -} - -message criu_restore_resp { - required int32 pid = 1; -} - -message criu_notify { - optional string script = 1; - optional int32 pid = 2; -} - -enum criu_req_type { - EMPTY = 0; - DUMP = 1; - RESTORE = 2; - CHECK = 3; - PRE_DUMP = 4; - PAGE_SERVER = 5; - - NOTIFY = 6; - - CPUINFO_DUMP = 7; - CPUINFO_CHECK = 8; - - FEATURE_CHECK = 9; - - VERSION = 10; - - WAIT_PID = 11; - PAGE_SERVER_CHLD = 12; -} - -/* - * List of features which can queried via - * CRIU_REQ_TYPE__FEATURE_CHECK - */ -message criu_features { - optional bool mem_track = 1; - optional bool lazy_pages = 2; - optional bool pidfd_store = 3; -} - -/* - * Request -- each type corresponds to must-be-there - * request arguments of respective type - */ - -message criu_req { - required criu_req_type type = 1; - - optional criu_opts opts = 2; - optional bool notify_success = 3; - - /* - * When set service won't close the connection but - * will wait for more req-s to appear. Works not - * for all request types. - */ - optional bool keep_open = 4; - /* - * 'features' can be used to query which features - * are supported by the installed criu/kernel - * via RPC. - */ - optional criu_features features = 5; - - /* 'pid' is used for WAIT_PID */ - optional uint32 pid = 6; -} - -/* - * Response -- it states whether the request was served - * and additional request-specific information - */ - -message criu_resp { - required criu_req_type type = 1; - required bool success = 2; - - optional criu_dump_resp dump = 3; - optional criu_restore_resp restore = 4; - optional criu_notify notify = 5; - optional criu_page_server_info ps = 6; - - optional int32 cr_errno = 7; - optional criu_features features = 8; - optional string cr_errmsg = 9; - optional criu_version version = 10; - - optional int32 status = 11; -} - -/* Answer for criu_req_type.VERSION requests */ -message criu_version { - required int32 major_number = 1; - required int32 minor_number = 2; - optional string gitid = 3; - optional int32 sublevel = 4; - optional int32 extra = 5; - optional string name = 6; -} diff --git a/vendor/github.com/containerd/console/.golangci.yml b/vendor/github.com/containerd/console/.golangci.yml deleted file mode 100644 index abe3d84bb16..00000000000 --- a/vendor/github.com/containerd/console/.golangci.yml +++ /dev/null @@ -1,20 +0,0 @@ -linters: - enable: - - gofmt - - goimports - - ineffassign - - misspell - - revive - - staticcheck - - structcheck - - unconvert - - unused - - varcheck - - vet - disable: - - errcheck - -run: - timeout: 3m - skip-dirs: - - vendor diff --git a/vendor/github.com/containerd/console/LICENSE b/vendor/github.com/containerd/console/LICENSE deleted file mode 100644 index 584149b6ee2..00000000000 --- a/vendor/github.com/containerd/console/LICENSE +++ /dev/null @@ -1,191 +0,0 @@ - - Apache License - Version 2.0, January 2004 - https://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - Copyright The containerd Authors - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - https://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/vendor/github.com/containerd/console/README.md b/vendor/github.com/containerd/console/README.md deleted file mode 100644 index a849a728f1e..00000000000 --- a/vendor/github.com/containerd/console/README.md +++ /dev/null @@ -1,29 +0,0 @@ -# console - -[![PkgGoDev](https://pkg.go.dev/badge/github.com/containerd/console)](https://pkg.go.dev/github.com/containerd/console) -[![Build Status](https://github.com/containerd/console/workflows/CI/badge.svg)](https://github.com/containerd/console/actions?query=workflow%3ACI) -[![Go Report Card](https://goreportcard.com/badge/github.com/containerd/console)](https://goreportcard.com/report/github.com/containerd/console) - -Golang package for dealing with consoles. Light on deps and a simple API. - -## Modifying the current process - -```go -current := console.Current() -defer current.Reset() - -if err := current.SetRaw(); err != nil { -} -ws, err := current.Size() -current.Resize(ws) -``` - -## Project details - -console is a containerd sub-project, licensed under the [Apache 2.0 license](./LICENSE). -As a containerd sub-project, you will find the: - * [Project governance](https://github.com/containerd/project/blob/main/GOVERNANCE.md), - * [Maintainers](https://github.com/containerd/project/blob/main/MAINTAINERS), - * and [Contributing guidelines](https://github.com/containerd/project/blob/main/CONTRIBUTING.md) - -information in our [`containerd/project`](https://github.com/containerd/project) repository. diff --git a/vendor/github.com/containerd/console/console.go b/vendor/github.com/containerd/console/console.go deleted file mode 100644 index dd587d88e07..00000000000 --- a/vendor/github.com/containerd/console/console.go +++ /dev/null @@ -1,90 +0,0 @@ -/* - Copyright The containerd Authors. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -package console - -import ( - "errors" - "io" - "os" -) - -var ( - ErrNotAConsole = errors.New("provided file is not a console") - ErrNotImplemented = errors.New("not implemented") -) - -type File interface { - io.ReadWriteCloser - - // Fd returns its file descriptor - Fd() uintptr - // Name returns its file name - Name() string -} - -type Console interface { - File - - // Resize resizes the console to the provided window size - Resize(WinSize) error - // ResizeFrom resizes the calling console to the size of the - // provided console - ResizeFrom(Console) error - // SetRaw sets the console in raw mode - SetRaw() error - // DisableEcho disables echo on the console - DisableEcho() error - // Reset restores the console to its original state - Reset() error - // Size returns the window size of the console - Size() (WinSize, error) -} - -// WinSize specifies the window size of the console -type WinSize struct { - // Height of the console - Height uint16 - // Width of the console - Width uint16 - x uint16 - y uint16 -} - -// Current returns the current process' console -func Current() (c Console) { - var err error - // Usually all three streams (stdin, stdout, and stderr) - // are open to the same console, but some might be redirected, - // so try all three. - for _, s := range []*os.File{os.Stderr, os.Stdout, os.Stdin} { - if c, err = ConsoleFromFile(s); err == nil { - return c - } - } - // One of the std streams should always be a console - // for the design of this function. - panic(err) -} - -// ConsoleFromFile returns a console using the provided file -// nolint:revive -func ConsoleFromFile(f File) (Console, error) { - if err := checkConsole(f); err != nil { - return nil, err - } - return newMaster(f) -} diff --git a/vendor/github.com/containerd/console/console_linux.go b/vendor/github.com/containerd/console/console_linux.go deleted file mode 100644 index 28b77b7a389..00000000000 --- a/vendor/github.com/containerd/console/console_linux.go +++ /dev/null @@ -1,281 +0,0 @@ -//go:build linux -// +build linux - -/* - Copyright The containerd Authors. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -package console - -import ( - "io" - "os" - "sync" - - "golang.org/x/sys/unix" -) - -const ( - maxEvents = 128 -) - -// Epoller manages multiple epoll consoles using edge-triggered epoll api so we -// dont have to deal with repeated wake-up of EPOLLER or EPOLLHUP. -// For more details, see: -// - https://github.com/systemd/systemd/pull/4262 -// - https://github.com/moby/moby/issues/27202 -// -// Example usage of Epoller and EpollConsole can be as follow: -// -// epoller, _ := NewEpoller() -// epollConsole, _ := epoller.Add(console) -// go epoller.Wait() -// var ( -// b bytes.Buffer -// wg sync.WaitGroup -// ) -// wg.Add(1) -// go func() { -// io.Copy(&b, epollConsole) -// wg.Done() -// }() -// // perform I/O on the console -// epollConsole.Shutdown(epoller.CloseConsole) -// wg.Wait() -// epollConsole.Close() -type Epoller struct { - efd int - mu sync.Mutex - fdMapping map[int]*EpollConsole - closeOnce sync.Once -} - -// NewEpoller returns an instance of epoller with a valid epoll fd. -func NewEpoller() (*Epoller, error) { - efd, err := unix.EpollCreate1(unix.EPOLL_CLOEXEC) - if err != nil { - return nil, err - } - return &Epoller{ - efd: efd, - fdMapping: make(map[int]*EpollConsole), - }, nil -} - -// Add creates an epoll console based on the provided console. The console will -// be registered with EPOLLET (i.e. using edge-triggered notification) and its -// file descriptor will be set to non-blocking mode. After this, user should use -// the return console to perform I/O. -func (e *Epoller) Add(console Console) (*EpollConsole, error) { - sysfd := int(console.Fd()) - // Set sysfd to non-blocking mode - if err := unix.SetNonblock(sysfd, true); err != nil { - return nil, err - } - - ev := unix.EpollEvent{ - Events: unix.EPOLLIN | unix.EPOLLOUT | unix.EPOLLRDHUP | unix.EPOLLET, - Fd: int32(sysfd), - } - if err := unix.EpollCtl(e.efd, unix.EPOLL_CTL_ADD, sysfd, &ev); err != nil { - return nil, err - } - ef := &EpollConsole{ - Console: console, - sysfd: sysfd, - readc: sync.NewCond(&sync.Mutex{}), - writec: sync.NewCond(&sync.Mutex{}), - } - e.mu.Lock() - e.fdMapping[sysfd] = ef - e.mu.Unlock() - return ef, nil -} - -// Wait starts the loop to wait for its consoles' notifications and signal -// appropriate console that it can perform I/O. -func (e *Epoller) Wait() error { - events := make([]unix.EpollEvent, maxEvents) - for { - n, err := unix.EpollWait(e.efd, events, -1) - if err != nil { - // EINTR: The call was interrupted by a signal handler before either - // any of the requested events occurred or the timeout expired - if err == unix.EINTR { - continue - } - return err - } - for i := 0; i < n; i++ { - ev := &events[i] - // the console is ready to be read from - if ev.Events&(unix.EPOLLIN|unix.EPOLLHUP|unix.EPOLLERR) != 0 { - if epfile := e.getConsole(int(ev.Fd)); epfile != nil { - epfile.signalRead() - } - } - // the console is ready to be written to - if ev.Events&(unix.EPOLLOUT|unix.EPOLLHUP|unix.EPOLLERR) != 0 { - if epfile := e.getConsole(int(ev.Fd)); epfile != nil { - epfile.signalWrite() - } - } - } - } -} - -// CloseConsole unregisters the console's file descriptor from epoll interface -func (e *Epoller) CloseConsole(fd int) error { - e.mu.Lock() - defer e.mu.Unlock() - delete(e.fdMapping, fd) - return unix.EpollCtl(e.efd, unix.EPOLL_CTL_DEL, fd, &unix.EpollEvent{}) -} - -func (e *Epoller) getConsole(sysfd int) *EpollConsole { - e.mu.Lock() - f := e.fdMapping[sysfd] - e.mu.Unlock() - return f -} - -// Close closes the epoll fd -func (e *Epoller) Close() error { - closeErr := os.ErrClosed // default to "file already closed" - e.closeOnce.Do(func() { - closeErr = unix.Close(e.efd) - }) - return closeErr -} - -// EpollConsole acts like a console but registers its file descriptor with an -// epoll fd and uses epoll API to perform I/O. -type EpollConsole struct { - Console - readc *sync.Cond - writec *sync.Cond - sysfd int - closed bool -} - -// Read reads up to len(p) bytes into p. It returns the number of bytes read -// (0 <= n <= len(p)) and any error encountered. -// -// If the console's read returns EAGAIN or EIO, we assume that it's a -// temporary error because the other side went away and wait for the signal -// generated by epoll event to continue. -func (ec *EpollConsole) Read(p []byte) (n int, err error) { - var read int - ec.readc.L.Lock() - defer ec.readc.L.Unlock() - for { - read, err = ec.Console.Read(p[n:]) - n += read - if err != nil { - var hangup bool - if perr, ok := err.(*os.PathError); ok { - hangup = (perr.Err == unix.EAGAIN || perr.Err == unix.EIO) - } else { - hangup = (err == unix.EAGAIN || err == unix.EIO) - } - // if the other end disappear, assume this is temporary and wait for the - // signal to continue again. Unless we didnt read anything and the - // console is already marked as closed then we should exit - if hangup && !(n == 0 && len(p) > 0 && ec.closed) { - ec.readc.Wait() - continue - } - } - break - } - // if we didnt read anything then return io.EOF to end gracefully - if n == 0 && len(p) > 0 && err == nil { - err = io.EOF - } - // signal for others that we finished the read - ec.readc.Signal() - return n, err -} - -// Writes len(p) bytes from p to the console. It returns the number of bytes -// written from p (0 <= n <= len(p)) and any error encountered that caused -// the write to stop early. -// -// If writes to the console returns EAGAIN or EIO, we assume that it's a -// temporary error because the other side went away and wait for the signal -// generated by epoll event to continue. -func (ec *EpollConsole) Write(p []byte) (n int, err error) { - var written int - ec.writec.L.Lock() - defer ec.writec.L.Unlock() - for { - written, err = ec.Console.Write(p[n:]) - n += written - if err != nil { - var hangup bool - if perr, ok := err.(*os.PathError); ok { - hangup = (perr.Err == unix.EAGAIN || perr.Err == unix.EIO) - } else { - hangup = (err == unix.EAGAIN || err == unix.EIO) - } - // if the other end disappears, assume this is temporary and wait for the - // signal to continue again. - if hangup { - ec.writec.Wait() - continue - } - } - // unrecoverable error, break the loop and return the error - break - } - if n < len(p) && err == nil { - err = io.ErrShortWrite - } - // signal for others that we finished the write - ec.writec.Signal() - return n, err -} - -// Shutdown closes the file descriptor and signals call waiters for this fd. -// It accepts a callback which will be called with the console's fd. The -// callback typically will be used to do further cleanup such as unregister the -// console's fd from the epoll interface. -// User should call Shutdown and wait for all I/O operation to be finished -// before closing the console. -func (ec *EpollConsole) Shutdown(close func(int) error) error { - ec.readc.L.Lock() - defer ec.readc.L.Unlock() - ec.writec.L.Lock() - defer ec.writec.L.Unlock() - - ec.readc.Broadcast() - ec.writec.Broadcast() - ec.closed = true - return close(ec.sysfd) -} - -// signalRead signals that the console is readable. -func (ec *EpollConsole) signalRead() { - ec.readc.L.Lock() - ec.readc.Signal() - ec.readc.L.Unlock() -} - -// signalWrite signals that the console is writable. -func (ec *EpollConsole) signalWrite() { - ec.writec.L.Lock() - ec.writec.Signal() - ec.writec.L.Unlock() -} diff --git a/vendor/github.com/containerd/console/console_other.go b/vendor/github.com/containerd/console/console_other.go deleted file mode 100644 index 933dfadddae..00000000000 --- a/vendor/github.com/containerd/console/console_other.go +++ /dev/null @@ -1,36 +0,0 @@ -//go:build !darwin && !freebsd && !linux && !netbsd && !openbsd && !solaris && !windows && !zos -// +build !darwin,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows,!zos - -/* - Copyright The containerd Authors. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -package console - -// NewPty creates a new pty pair -// The master is returned as the first console and a string -// with the path to the pty slave is returned as the second -func NewPty() (Console, string, error) { - return nil, "", ErrNotImplemented -} - -// checkConsole checks if the provided file is a console -func checkConsole(f File) error { - return ErrNotAConsole -} - -func newMaster(f File) (Console, error) { - return nil, ErrNotImplemented -} diff --git a/vendor/github.com/containerd/console/console_unix.go b/vendor/github.com/containerd/console/console_unix.go deleted file mode 100644 index 161f5d126cb..00000000000 --- a/vendor/github.com/containerd/console/console_unix.go +++ /dev/null @@ -1,157 +0,0 @@ -//go:build darwin || freebsd || linux || netbsd || openbsd || zos -// +build darwin freebsd linux netbsd openbsd zos - -/* - Copyright The containerd Authors. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -package console - -import ( - "golang.org/x/sys/unix" -) - -// NewPty creates a new pty pair -// The master is returned as the first console and a string -// with the path to the pty slave is returned as the second -func NewPty() (Console, string, error) { - f, err := openpt() - if err != nil { - return nil, "", err - } - slave, err := ptsname(f) - if err != nil { - return nil, "", err - } - if err := unlockpt(f); err != nil { - return nil, "", err - } - m, err := newMaster(f) - if err != nil { - return nil, "", err - } - return m, slave, nil -} - -type master struct { - f File - original *unix.Termios -} - -func (m *master) Read(b []byte) (int, error) { - return m.f.Read(b) -} - -func (m *master) Write(b []byte) (int, error) { - return m.f.Write(b) -} - -func (m *master) Close() error { - return m.f.Close() -} - -func (m *master) Resize(ws WinSize) error { - return tcswinsz(m.f.Fd(), ws) -} - -func (m *master) ResizeFrom(c Console) error { - ws, err := c.Size() - if err != nil { - return err - } - return m.Resize(ws) -} - -func (m *master) Reset() error { - if m.original == nil { - return nil - } - return tcset(m.f.Fd(), m.original) -} - -func (m *master) getCurrent() (unix.Termios, error) { - var termios unix.Termios - if err := tcget(m.f.Fd(), &termios); err != nil { - return unix.Termios{}, err - } - return termios, nil -} - -func (m *master) SetRaw() error { - rawState, err := m.getCurrent() - if err != nil { - return err - } - rawState = cfmakeraw(rawState) - rawState.Oflag = rawState.Oflag | unix.OPOST - return tcset(m.f.Fd(), &rawState) -} - -func (m *master) DisableEcho() error { - rawState, err := m.getCurrent() - if err != nil { - return err - } - rawState.Lflag = rawState.Lflag &^ unix.ECHO - return tcset(m.f.Fd(), &rawState) -} - -func (m *master) Size() (WinSize, error) { - return tcgwinsz(m.f.Fd()) -} - -func (m *master) Fd() uintptr { - return m.f.Fd() -} - -func (m *master) Name() string { - return m.f.Name() -} - -// checkConsole checks if the provided file is a console -func checkConsole(f File) error { - var termios unix.Termios - if tcget(f.Fd(), &termios) != nil { - return ErrNotAConsole - } - return nil -} - -func newMaster(f File) (Console, error) { - m := &master{ - f: f, - } - t, err := m.getCurrent() - if err != nil { - return nil, err - } - m.original = &t - return m, nil -} - -// ClearONLCR sets the necessary tty_ioctl(4)s to ensure that a pty pair -// created by us acts normally. In particular, a not-very-well-known default of -// Linux unix98 ptys is that they have +onlcr by default. While this isn't a -// problem for terminal emulators, because we relay data from the terminal we -// also relay that funky line discipline. -func ClearONLCR(fd uintptr) error { - return setONLCR(fd, false) -} - -// SetONLCR sets the necessary tty_ioctl(4)s to ensure that a pty pair -// created by us acts as intended for a terminal emulator. -func SetONLCR(fd uintptr) error { - return setONLCR(fd, true) -} diff --git a/vendor/github.com/containerd/console/console_windows.go b/vendor/github.com/containerd/console/console_windows.go deleted file mode 100644 index 6896db1825f..00000000000 --- a/vendor/github.com/containerd/console/console_windows.go +++ /dev/null @@ -1,219 +0,0 @@ -/* - Copyright The containerd Authors. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -package console - -import ( - "errors" - "fmt" - "os" - - "golang.org/x/sys/windows" -) - -var vtInputSupported bool - -func (m *master) initStdios() { - // Note: We discard console mode warnings, because in/out can be redirected. - // - // TODO: Investigate opening CONOUT$/CONIN$ to handle this correctly - - m.in = windows.Handle(os.Stdin.Fd()) - if err := windows.GetConsoleMode(m.in, &m.inMode); err == nil { - // Validate that windows.ENABLE_VIRTUAL_TERMINAL_INPUT is supported, but do not set it. - if err = windows.SetConsoleMode(m.in, m.inMode|windows.ENABLE_VIRTUAL_TERMINAL_INPUT); err == nil { - vtInputSupported = true - } - // Unconditionally set the console mode back even on failure because SetConsoleMode - // remembers invalid bits on input handles. - windows.SetConsoleMode(m.in, m.inMode) - } - - m.out = windows.Handle(os.Stdout.Fd()) - if err := windows.GetConsoleMode(m.out, &m.outMode); err == nil { - if err := windows.SetConsoleMode(m.out, m.outMode|windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING); err == nil { - m.outMode |= windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING - } else { - windows.SetConsoleMode(m.out, m.outMode) - } - } - - m.err = windows.Handle(os.Stderr.Fd()) - if err := windows.GetConsoleMode(m.err, &m.errMode); err == nil { - if err := windows.SetConsoleMode(m.err, m.errMode|windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING); err == nil { - m.errMode |= windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING - } else { - windows.SetConsoleMode(m.err, m.errMode) - } - } -} - -type master struct { - in windows.Handle - inMode uint32 - - out windows.Handle - outMode uint32 - - err windows.Handle - errMode uint32 -} - -func (m *master) SetRaw() error { - if err := makeInputRaw(m.in, m.inMode); err != nil { - return err - } - - // Set StdOut and StdErr to raw mode, we ignore failures since - // windows.DISABLE_NEWLINE_AUTO_RETURN might not be supported on this version of - // Windows. - - windows.SetConsoleMode(m.out, m.outMode|windows.DISABLE_NEWLINE_AUTO_RETURN) - - windows.SetConsoleMode(m.err, m.errMode|windows.DISABLE_NEWLINE_AUTO_RETURN) - - return nil -} - -func (m *master) Reset() error { - var errs []error - - for _, s := range []struct { - fd windows.Handle - mode uint32 - }{ - {m.in, m.inMode}, - {m.out, m.outMode}, - {m.err, m.errMode}, - } { - if err := windows.SetConsoleMode(s.fd, s.mode); err != nil { - // we can't just abort on the first error, otherwise we might leave - // the console in an unexpected state. - errs = append(errs, fmt.Errorf("unable to restore console mode: %w", err)) - } - } - - if len(errs) > 0 { - return errs[0] - } - - return nil -} - -func (m *master) Size() (WinSize, error) { - var info windows.ConsoleScreenBufferInfo - err := windows.GetConsoleScreenBufferInfo(m.out, &info) - if err != nil { - return WinSize{}, fmt.Errorf("unable to get console info: %w", err) - } - - winsize := WinSize{ - Width: uint16(info.Window.Right - info.Window.Left + 1), - Height: uint16(info.Window.Bottom - info.Window.Top + 1), - } - - return winsize, nil -} - -func (m *master) Resize(ws WinSize) error { - return ErrNotImplemented -} - -func (m *master) ResizeFrom(c Console) error { - return ErrNotImplemented -} - -func (m *master) DisableEcho() error { - mode := m.inMode &^ windows.ENABLE_ECHO_INPUT - mode |= windows.ENABLE_PROCESSED_INPUT - mode |= windows.ENABLE_LINE_INPUT - - if err := windows.SetConsoleMode(m.in, mode); err != nil { - return fmt.Errorf("unable to set console to disable echo: %w", err) - } - - return nil -} - -func (m *master) Close() error { - return nil -} - -func (m *master) Read(b []byte) (int, error) { - return os.Stdin.Read(b) -} - -func (m *master) Write(b []byte) (int, error) { - return os.Stdout.Write(b) -} - -func (m *master) Fd() uintptr { - return uintptr(m.in) -} - -// on windows, console can only be made from os.Std{in,out,err}, hence there -// isnt a single name here we can use. Return a dummy "console" value in this -// case should be sufficient. -func (m *master) Name() string { - return "console" -} - -// makeInputRaw puts the terminal (Windows Console) connected to the given -// file descriptor into raw mode -func makeInputRaw(fd windows.Handle, mode uint32) error { - // See - // -- https://msdn.microsoft.com/en-us/library/windows/desktop/ms686033(v=vs.85).aspx - // -- https://msdn.microsoft.com/en-us/library/windows/desktop/ms683462(v=vs.85).aspx - - // Disable these modes - mode &^= windows.ENABLE_ECHO_INPUT - mode &^= windows.ENABLE_LINE_INPUT - mode &^= windows.ENABLE_MOUSE_INPUT - mode &^= windows.ENABLE_WINDOW_INPUT - mode &^= windows.ENABLE_PROCESSED_INPUT - - // Enable these modes - mode |= windows.ENABLE_EXTENDED_FLAGS - mode |= windows.ENABLE_INSERT_MODE - mode |= windows.ENABLE_QUICK_EDIT_MODE - - if vtInputSupported { - mode |= windows.ENABLE_VIRTUAL_TERMINAL_INPUT - } - - if err := windows.SetConsoleMode(fd, mode); err != nil { - return fmt.Errorf("unable to set console to raw mode: %w", err) - } - - return nil -} - -func checkConsole(f File) error { - var mode uint32 - if err := windows.GetConsoleMode(windows.Handle(f.Fd()), &mode); err != nil { - return err - } - return nil -} - -func newMaster(f File) (Console, error) { - if f != os.Stdin && f != os.Stdout && f != os.Stderr { - return nil, errors.New("creating a console from a file is not supported on windows") - } - m := &master{} - m.initStdios() - return m, nil -} diff --git a/vendor/github.com/containerd/console/pty_freebsd_cgo.go b/vendor/github.com/containerd/console/pty_freebsd_cgo.go deleted file mode 100644 index 22368623aab..00000000000 --- a/vendor/github.com/containerd/console/pty_freebsd_cgo.go +++ /dev/null @@ -1,46 +0,0 @@ -//go:build freebsd && cgo -// +build freebsd,cgo - -/* - Copyright The containerd Authors. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -package console - -import ( - "fmt" - "os" -) - -/* -#include -#include -#include -*/ -import "C" - -// openpt allocates a new pseudo-terminal and establishes a connection with its -// control device. -func openpt() (*os.File, error) { - fd, err := C.posix_openpt(C.O_RDWR) - if err != nil { - return nil, fmt.Errorf("posix_openpt: %w", err) - } - if _, err := C.grantpt(fd); err != nil { - C.close(fd) - return nil, fmt.Errorf("grantpt: %w", err) - } - return os.NewFile(uintptr(fd), ""), nil -} diff --git a/vendor/github.com/containerd/console/pty_freebsd_nocgo.go b/vendor/github.com/containerd/console/pty_freebsd_nocgo.go deleted file mode 100644 index ceb90a47b81..00000000000 --- a/vendor/github.com/containerd/console/pty_freebsd_nocgo.go +++ /dev/null @@ -1,37 +0,0 @@ -//go:build freebsd && !cgo -// +build freebsd,!cgo - -/* - Copyright The containerd Authors. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -package console - -import ( - "os" -) - -// -// Implementing the functions below requires cgo support. Non-cgo stubs -// versions are defined below to enable cross-compilation of source code -// that depends on these functions, but the resultant cross-compiled -// binaries cannot actually be used. If the stub function(s) below are -// actually invoked they will display an error message and cause the -// calling process to exit. -// - -func openpt() (*os.File, error) { - panic("openpt() support requires cgo.") -} diff --git a/vendor/github.com/containerd/console/pty_unix.go b/vendor/github.com/containerd/console/pty_unix.go deleted file mode 100644 index f5a5b8058c6..00000000000 --- a/vendor/github.com/containerd/console/pty_unix.go +++ /dev/null @@ -1,31 +0,0 @@ -//go:build darwin || linux || netbsd || openbsd -// +build darwin linux netbsd openbsd - -/* - Copyright The containerd Authors. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -package console - -import ( - "os" - - "golang.org/x/sys/unix" -) - -// openpt allocates a new pseudo-terminal by opening the /dev/ptmx device -func openpt() (*os.File, error) { - return os.OpenFile("/dev/ptmx", unix.O_RDWR|unix.O_NOCTTY|unix.O_CLOEXEC, 0) -} diff --git a/vendor/github.com/containerd/console/pty_zos.go b/vendor/github.com/containerd/console/pty_zos.go deleted file mode 100644 index 58f59aba58c..00000000000 --- a/vendor/github.com/containerd/console/pty_zos.go +++ /dev/null @@ -1,43 +0,0 @@ -//go:build zos -// +build zos - -/* - Copyright The containerd Authors. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -package console - -import ( - "fmt" - "os" -) - -// openpt allocates a new pseudo-terminal by opening the first available /dev/ptypXX device -func openpt() (*os.File, error) { - var f *os.File - var err error - for i := 0; ; i++ { - ptyp := fmt.Sprintf("/dev/ptyp%04d", i) - f, err = os.OpenFile(ptyp, os.O_RDWR, 0600) - if err == nil { - break - } - if os.IsNotExist(err) { - return nil, err - } - // else probably Resource Busy - } - return f, nil -} diff --git a/vendor/github.com/containerd/console/tc_darwin.go b/vendor/github.com/containerd/console/tc_darwin.go deleted file mode 100644 index 787154580f6..00000000000 --- a/vendor/github.com/containerd/console/tc_darwin.go +++ /dev/null @@ -1,44 +0,0 @@ -/* - Copyright The containerd Authors. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -package console - -import ( - "fmt" - "os" - - "golang.org/x/sys/unix" -) - -const ( - cmdTcGet = unix.TIOCGETA - cmdTcSet = unix.TIOCSETA -) - -// unlockpt unlocks the slave pseudoterminal device corresponding to the master pseudoterminal referred to by f. -// unlockpt should be called before opening the slave side of a pty. -func unlockpt(f *os.File) error { - return unix.IoctlSetPointerInt(int(f.Fd()), unix.TIOCPTYUNLK, 0) -} - -// ptsname retrieves the name of the first available pts for the given master. -func ptsname(f *os.File) (string, error) { - n, err := unix.IoctlGetInt(int(f.Fd()), unix.TIOCPTYGNAME) - if err != nil { - return "", err - } - return fmt.Sprintf("/dev/pts/%d", n), nil -} diff --git a/vendor/github.com/containerd/console/tc_freebsd_cgo.go b/vendor/github.com/containerd/console/tc_freebsd_cgo.go deleted file mode 100644 index 33282579411..00000000000 --- a/vendor/github.com/containerd/console/tc_freebsd_cgo.go +++ /dev/null @@ -1,58 +0,0 @@ -//go:build freebsd && cgo -// +build freebsd,cgo - -/* - Copyright The containerd Authors. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -package console - -import ( - "fmt" - "os" - - "golang.org/x/sys/unix" -) - -/* -#include -#include -*/ -import "C" - -const ( - cmdTcGet = unix.TIOCGETA - cmdTcSet = unix.TIOCSETA -) - -// unlockpt unlocks the slave pseudoterminal device corresponding to the master pseudoterminal referred to by f. -// unlockpt should be called before opening the slave side of a pty. -func unlockpt(f *os.File) error { - fd := C.int(f.Fd()) - if _, err := C.unlockpt(fd); err != nil { - C.close(fd) - return fmt.Errorf("unlockpt: %w", err) - } - return nil -} - -// ptsname retrieves the name of the first available pts for the given master. -func ptsname(f *os.File) (string, error) { - n, err := unix.IoctlGetInt(int(f.Fd()), unix.TIOCGPTN) - if err != nil { - return "", err - } - return fmt.Sprintf("/dev/pts/%d", n), nil -} diff --git a/vendor/github.com/containerd/console/tc_freebsd_nocgo.go b/vendor/github.com/containerd/console/tc_freebsd_nocgo.go deleted file mode 100644 index 18a9b9cbea9..00000000000 --- a/vendor/github.com/containerd/console/tc_freebsd_nocgo.go +++ /dev/null @@ -1,56 +0,0 @@ -//go:build freebsd && !cgo -// +build freebsd,!cgo - -/* - Copyright The containerd Authors. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -package console - -import ( - "fmt" - "os" - - "golang.org/x/sys/unix" -) - -const ( - cmdTcGet = unix.TIOCGETA - cmdTcSet = unix.TIOCSETA -) - -// -// Implementing the functions below requires cgo support. Non-cgo stubs -// versions are defined below to enable cross-compilation of source code -// that depends on these functions, but the resultant cross-compiled -// binaries cannot actually be used. If the stub function(s) below are -// actually invoked they will display an error message and cause the -// calling process to exit. -// - -// unlockpt unlocks the slave pseudoterminal device corresponding to the master pseudoterminal referred to by f. -// unlockpt should be called before opening the slave side of a pty. -func unlockpt(f *os.File) error { - panic("unlockpt() support requires cgo.") -} - -// ptsname retrieves the name of the first available pts for the given master. -func ptsname(f *os.File) (string, error) { - n, err := unix.IoctlGetInt(int(f.Fd()), unix.TIOCGPTN) - if err != nil { - return "", err - } - return fmt.Sprintf("/dev/pts/%d", n), nil -} diff --git a/vendor/github.com/containerd/console/tc_linux.go b/vendor/github.com/containerd/console/tc_linux.go deleted file mode 100644 index 7d552ea4ba1..00000000000 --- a/vendor/github.com/containerd/console/tc_linux.go +++ /dev/null @@ -1,51 +0,0 @@ -/* - Copyright The containerd Authors. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -package console - -import ( - "fmt" - "os" - "unsafe" - - "golang.org/x/sys/unix" -) - -const ( - cmdTcGet = unix.TCGETS - cmdTcSet = unix.TCSETS -) - -// unlockpt unlocks the slave pseudoterminal device corresponding to the master pseudoterminal referred to by f. -// unlockpt should be called before opening the slave side of a pty. -func unlockpt(f *os.File) error { - var u int32 - // XXX do not use unix.IoctlSetPointerInt here, see commit dbd69c59b81. - if _, _, err := unix.Syscall(unix.SYS_IOCTL, f.Fd(), unix.TIOCSPTLCK, uintptr(unsafe.Pointer(&u))); err != 0 { - return err - } - return nil -} - -// ptsname retrieves the name of the first available pts for the given master. -func ptsname(f *os.File) (string, error) { - var u uint32 - // XXX do not use unix.IoctlGetInt here, see commit dbd69c59b81. - if _, _, err := unix.Syscall(unix.SYS_IOCTL, f.Fd(), unix.TIOCGPTN, uintptr(unsafe.Pointer(&u))); err != 0 { - return "", err - } - return fmt.Sprintf("/dev/pts/%d", u), nil -} diff --git a/vendor/github.com/containerd/console/tc_netbsd.go b/vendor/github.com/containerd/console/tc_netbsd.go deleted file mode 100644 index 71227aefdff..00000000000 --- a/vendor/github.com/containerd/console/tc_netbsd.go +++ /dev/null @@ -1,45 +0,0 @@ -/* - Copyright The containerd Authors. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -package console - -import ( - "bytes" - "os" - - "golang.org/x/sys/unix" -) - -const ( - cmdTcGet = unix.TIOCGETA - cmdTcSet = unix.TIOCSETA -) - -// unlockpt unlocks the slave pseudoterminal device corresponding to the master pseudoterminal referred to by f. -// unlockpt should be called before opening the slave side of a pty. -// This does not exist on NetBSD, it does not allocate controlling terminals on open -func unlockpt(f *os.File) error { - return nil -} - -// ptsname retrieves the name of the first available pts for the given master. -func ptsname(f *os.File) (string, error) { - ptm, err := unix.IoctlGetPtmget(int(f.Fd()), unix.TIOCPTSNAME) - if err != nil { - return "", err - } - return string(ptm.Sn[:bytes.IndexByte(ptm.Sn[:], 0)]), nil -} diff --git a/vendor/github.com/containerd/console/tc_openbsd_cgo.go b/vendor/github.com/containerd/console/tc_openbsd_cgo.go deleted file mode 100644 index 0e76f6cc3e0..00000000000 --- a/vendor/github.com/containerd/console/tc_openbsd_cgo.go +++ /dev/null @@ -1,52 +0,0 @@ -//go:build openbsd && cgo -// +build openbsd,cgo - -/* - Copyright The containerd Authors. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -package console - -import ( - "os" - - "golang.org/x/sys/unix" -) - -//#include -import "C" - -const ( - cmdTcGet = unix.TIOCGETA - cmdTcSet = unix.TIOCSETA -) - -// ptsname retrieves the name of the first available pts for the given master. -func ptsname(f *os.File) (string, error) { - ptspath, err := C.ptsname(C.int(f.Fd())) - if err != nil { - return "", err - } - return C.GoString(ptspath), nil -} - -// unlockpt unlocks the slave pseudoterminal device corresponding to the master pseudoterminal referred to by f. -// unlockpt should be called before opening the slave side of a pty. -func unlockpt(f *os.File) error { - if _, err := C.grantpt(C.int(f.Fd())); err != nil { - return err - } - return nil -} diff --git a/vendor/github.com/containerd/console/tc_openbsd_nocgo.go b/vendor/github.com/containerd/console/tc_openbsd_nocgo.go deleted file mode 100644 index dca92418b0e..00000000000 --- a/vendor/github.com/containerd/console/tc_openbsd_nocgo.go +++ /dev/null @@ -1,48 +0,0 @@ -//go:build openbsd && !cgo -// +build openbsd,!cgo - -/* - Copyright The containerd Authors. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -// -// Implementing the functions below requires cgo support. Non-cgo stubs -// versions are defined below to enable cross-compilation of source code -// that depends on these functions, but the resultant cross-compiled -// binaries cannot actually be used. If the stub function(s) below are -// actually invoked they will display an error message and cause the -// calling process to exit. -// - -package console - -import ( - "os" - - "golang.org/x/sys/unix" -) - -const ( - cmdTcGet = unix.TIOCGETA - cmdTcSet = unix.TIOCSETA -) - -func ptsname(f *os.File) (string, error) { - panic("ptsname() support requires cgo.") -} - -func unlockpt(f *os.File) error { - panic("unlockpt() support requires cgo.") -} diff --git a/vendor/github.com/containerd/console/tc_unix.go b/vendor/github.com/containerd/console/tc_unix.go deleted file mode 100644 index 2ecf188fca3..00000000000 --- a/vendor/github.com/containerd/console/tc_unix.go +++ /dev/null @@ -1,92 +0,0 @@ -//go:build darwin || freebsd || linux || netbsd || openbsd || zos -// +build darwin freebsd linux netbsd openbsd zos - -/* - Copyright The containerd Authors. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -package console - -import ( - "golang.org/x/sys/unix" -) - -func tcget(fd uintptr, p *unix.Termios) error { - termios, err := unix.IoctlGetTermios(int(fd), cmdTcGet) - if err != nil { - return err - } - *p = *termios - return nil -} - -func tcset(fd uintptr, p *unix.Termios) error { - return unix.IoctlSetTermios(int(fd), cmdTcSet, p) -} - -func tcgwinsz(fd uintptr) (WinSize, error) { - var ws WinSize - - uws, err := unix.IoctlGetWinsize(int(fd), unix.TIOCGWINSZ) - if err != nil { - return ws, err - } - - // Translate from unix.Winsize to console.WinSize - ws.Height = uws.Row - ws.Width = uws.Col - ws.x = uws.Xpixel - ws.y = uws.Ypixel - return ws, nil -} - -func tcswinsz(fd uintptr, ws WinSize) error { - // Translate from console.WinSize to unix.Winsize - - var uws unix.Winsize - uws.Row = ws.Height - uws.Col = ws.Width - uws.Xpixel = ws.x - uws.Ypixel = ws.y - - return unix.IoctlSetWinsize(int(fd), unix.TIOCSWINSZ, &uws) -} - -func setONLCR(fd uintptr, enable bool) error { - var termios unix.Termios - if err := tcget(fd, &termios); err != nil { - return err - } - if enable { - // Set +onlcr so we can act like a real terminal - termios.Oflag |= unix.ONLCR - } else { - // Set -onlcr so we don't have to deal with \r. - termios.Oflag &^= unix.ONLCR - } - return tcset(fd, &termios) -} - -func cfmakeraw(t unix.Termios) unix.Termios { - t.Iflag &^= (unix.IGNBRK | unix.BRKINT | unix.PARMRK | unix.ISTRIP | unix.INLCR | unix.IGNCR | unix.ICRNL | unix.IXON) - t.Oflag &^= unix.OPOST - t.Lflag &^= (unix.ECHO | unix.ECHONL | unix.ICANON | unix.ISIG | unix.IEXTEN) - t.Cflag &^= (unix.CSIZE | unix.PARENB) - t.Cflag |= unix.CS8 - t.Cc[unix.VMIN] = 1 - t.Cc[unix.VTIME] = 0 - - return t -} diff --git a/vendor/github.com/containerd/console/tc_zos.go b/vendor/github.com/containerd/console/tc_zos.go deleted file mode 100644 index fc90ba5fb86..00000000000 --- a/vendor/github.com/containerd/console/tc_zos.go +++ /dev/null @@ -1,39 +0,0 @@ -/* - Copyright The containerd Authors. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -package console - -import ( - "os" - "strings" - - "golang.org/x/sys/unix" -) - -const ( - cmdTcGet = unix.TCGETS - cmdTcSet = unix.TCSETS -) - -// unlockpt is a no-op on zos. -func unlockpt(_ *os.File) error { - return nil -} - -// ptsname retrieves the name of the first available pts for the given master. -func ptsname(f *os.File) (string, error) { - return "/dev/ttyp" + strings.TrimPrefix(f.Name(), "/dev/ptyp"), nil -} diff --git a/vendor/github.com/google/cadvisor/container/libcontainer/handler.go b/vendor/github.com/google/cadvisor/container/libcontainer/handler.go index d8b46b975b2..9f05a52a49d 100644 --- a/vendor/github.com/google/cadvisor/container/libcontainer/handler.go +++ b/vendor/github.com/google/cadvisor/container/libcontainer/handler.go @@ -28,7 +28,6 @@ import ( "strings" "time" - "github.com/opencontainers/runc/libcontainer" "github.com/opencontainers/runc/libcontainer/cgroups" "github.com/opencontainers/runc/libcontainer/cgroups/fs2" "k8s.io/klog/v2" @@ -89,10 +88,7 @@ func (h *Handler) GetStats() (*info.ContainerStats, error) { } klog.V(4).Infof("Ignoring errors when gathering stats for root cgroup since some controllers don't have stats on the root cgroup: %v", err) } - libcontainerStats := &libcontainer.Stats{ - CgroupStats: cgroupStats, - } - stats := newContainerStats(libcontainerStats, h.includedMetrics) + stats := newContainerStats(cgroupStats, h.includedMetrics) if h.includedMetrics.Has(container.ProcessSchedulerMetrics) { stats.Cpu.Schedstat, err = h.schedulerStatsFromProcs() @@ -888,28 +884,6 @@ func setHugepageStats(s *cgroups.Stats, ret *info.ContainerStats) { } } -func setNetworkStats(libcontainerStats *libcontainer.Stats, ret *info.ContainerStats) { - ret.Network.Interfaces = make([]info.InterfaceStats, len(libcontainerStats.Interfaces)) - for i := range libcontainerStats.Interfaces { - ret.Network.Interfaces[i] = info.InterfaceStats{ - Name: libcontainerStats.Interfaces[i].Name, - RxBytes: libcontainerStats.Interfaces[i].RxBytes, - RxPackets: libcontainerStats.Interfaces[i].RxPackets, - RxErrors: libcontainerStats.Interfaces[i].RxErrors, - RxDropped: libcontainerStats.Interfaces[i].RxDropped, - TxBytes: libcontainerStats.Interfaces[i].TxBytes, - TxPackets: libcontainerStats.Interfaces[i].TxPackets, - TxErrors: libcontainerStats.Interfaces[i].TxErrors, - TxDropped: libcontainerStats.Interfaces[i].TxDropped, - } - } - - // Add to base struct for backwards compatibility. - if len(ret.Network.Interfaces) > 0 { - ret.Network.InterfaceStats = ret.Network.Interfaces[0] - } -} - // read from pids path not cpu func setThreadsStats(s *cgroups.Stats, ret *info.ContainerStats) { if s != nil { @@ -918,12 +892,12 @@ func setThreadsStats(s *cgroups.Stats, ret *info.ContainerStats) { } } -func newContainerStats(libcontainerStats *libcontainer.Stats, includedMetrics container.MetricSet) *info.ContainerStats { +func newContainerStats(cgroupStats *cgroups.Stats, includedMetrics container.MetricSet) *info.ContainerStats { ret := &info.ContainerStats{ Timestamp: time.Now(), } - if s := libcontainerStats.CgroupStats; s != nil { + if s := cgroupStats; s != nil { setCPUStats(s, ret, includedMetrics.Has(container.PerCpuUsageMetrics)) if includedMetrics.Has(container.DiskIOMetrics) { setDiskIoStats(s, ret) @@ -939,8 +913,5 @@ func newContainerStats(libcontainerStats *libcontainer.Stats, includedMetrics co setCPUSetStats(s, ret) } } - if len(libcontainerStats.Interfaces) > 0 { - setNetworkStats(libcontainerStats, ret) - } return ret } diff --git a/vendor/github.com/google/cadvisor/utils/sysfs/sysfs.go b/vendor/github.com/google/cadvisor/utils/sysfs/sysfs.go index dbf7e000e4f..f2aedfc757d 100644 --- a/vendor/github.com/google/cadvisor/utils/sysfs/sysfs.go +++ b/vendor/github.com/google/cadvisor/utils/sysfs/sysfs.go @@ -254,10 +254,8 @@ func (fs *realSysFs) IsBlockDeviceHidden(name string) (bool, error) { if err != nil { return false, fmt.Errorf("failed to read %s: %w", devHiddenPath, err) } - if string(hidden) == "1" { - return true, nil - } - return false, nil + + return strings.TrimSpace(string(hidden)) == "1", nil } func (fs *realSysFs) GetBlockDeviceScheduler(name string) (string, error) { diff --git a/vendor/github.com/opencontainers/runc/libcontainer/README.md b/vendor/github.com/opencontainers/runc/libcontainer/README.md deleted file mode 100644 index 211c8c91e05..00000000000 --- a/vendor/github.com/opencontainers/runc/libcontainer/README.md +++ /dev/null @@ -1,318 +0,0 @@ -# libcontainer - -[![Go Reference](https://pkg.go.dev/badge/github.com/opencontainers/runc/libcontainer.svg)](https://pkg.go.dev/github.com/opencontainers/runc/libcontainer) - -Libcontainer provides a native Go implementation for creating containers -with namespaces, cgroups, capabilities, and filesystem access controls. -It allows you to manage the lifecycle of the container performing additional operations -after the container is created. - - -#### Container -A container is a self contained execution environment that shares the kernel of the -host system and which is (optionally) isolated from other containers in the system. - -#### Using libcontainer - -Because containers are spawned in a two step process you will need a binary that -will be executed as the init process for the container. In libcontainer, we use -the current binary (/proc/self/exe) to be executed as the init process, and use -arg "init", we call the first step process "bootstrap", so you always need a "init" -function as the entry of "bootstrap". - -In addition to the go init function the early stage bootstrap is handled by importing -[nsenter](https://github.com/opencontainers/runc/blob/master/libcontainer/nsenter/README.md). - -```go -import ( - _ "github.com/opencontainers/runc/libcontainer/nsenter" -) - -func init() { - if len(os.Args) > 1 && os.Args[1] == "init" { - runtime.GOMAXPROCS(1) - runtime.LockOSThread() - factory, _ := libcontainer.New("") - if err := factory.StartInitialization(); err != nil { - logrus.Fatal(err) - } - panic("--this line should have never been executed, congratulations--") - } -} -``` - -Then to create a container you first have to initialize an instance of a factory -that will handle the creation and initialization for a container. - -```go -factory, err := libcontainer.New("/var/lib/container", libcontainer.Cgroupfs, libcontainer.InitArgs(os.Args[0], "init")) -if err != nil { - logrus.Fatal(err) - return -} -``` - -Once you have an instance of the factory created we can create a configuration -struct describing how the container is to be created. A sample would look similar to this: - -```go -defaultMountFlags := unix.MS_NOEXEC | unix.MS_NOSUID | unix.MS_NODEV -var devices []*configs.DeviceRule -for _, device := range specconv.AllowedDevices { - devices = append(devices, &device.Rule) -} -config := &configs.Config{ - Rootfs: "/your/path/to/rootfs", - Capabilities: &configs.Capabilities{ - Bounding: []string{ - "CAP_CHOWN", - "CAP_DAC_OVERRIDE", - "CAP_FSETID", - "CAP_FOWNER", - "CAP_MKNOD", - "CAP_NET_RAW", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETFCAP", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE", - "CAP_SYS_CHROOT", - "CAP_KILL", - "CAP_AUDIT_WRITE", - }, - Effective: []string{ - "CAP_CHOWN", - "CAP_DAC_OVERRIDE", - "CAP_FSETID", - "CAP_FOWNER", - "CAP_MKNOD", - "CAP_NET_RAW", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETFCAP", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE", - "CAP_SYS_CHROOT", - "CAP_KILL", - "CAP_AUDIT_WRITE", - }, - Permitted: []string{ - "CAP_CHOWN", - "CAP_DAC_OVERRIDE", - "CAP_FSETID", - "CAP_FOWNER", - "CAP_MKNOD", - "CAP_NET_RAW", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETFCAP", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE", - "CAP_SYS_CHROOT", - "CAP_KILL", - "CAP_AUDIT_WRITE", - }, - Ambient: []string{ - "CAP_CHOWN", - "CAP_DAC_OVERRIDE", - "CAP_FSETID", - "CAP_FOWNER", - "CAP_MKNOD", - "CAP_NET_RAW", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETFCAP", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE", - "CAP_SYS_CHROOT", - "CAP_KILL", - "CAP_AUDIT_WRITE", - }, - }, - Namespaces: configs.Namespaces([]configs.Namespace{ - {Type: configs.NEWNS}, - {Type: configs.NEWUTS}, - {Type: configs.NEWIPC}, - {Type: configs.NEWPID}, - {Type: configs.NEWUSER}, - {Type: configs.NEWNET}, - {Type: configs.NEWCGROUP}, - }), - Cgroups: &configs.Cgroup{ - Name: "test-container", - Parent: "system", - Resources: &configs.Resources{ - MemorySwappiness: nil, - Devices: devices, - }, - }, - MaskPaths: []string{ - "/proc/kcore", - "/sys/firmware", - }, - ReadonlyPaths: []string{ - "/proc/sys", "/proc/sysrq-trigger", "/proc/irq", "/proc/bus", - }, - Devices: specconv.AllowedDevices, - Hostname: "testing", - Mounts: []*configs.Mount{ - { - Source: "proc", - Destination: "/proc", - Device: "proc", - Flags: defaultMountFlags, - }, - { - Source: "tmpfs", - Destination: "/dev", - Device: "tmpfs", - Flags: unix.MS_NOSUID | unix.MS_STRICTATIME, - Data: "mode=755", - }, - { - Source: "devpts", - Destination: "/dev/pts", - Device: "devpts", - Flags: unix.MS_NOSUID | unix.MS_NOEXEC, - Data: "newinstance,ptmxmode=0666,mode=0620,gid=5", - }, - { - Device: "tmpfs", - Source: "shm", - Destination: "/dev/shm", - Data: "mode=1777,size=65536k", - Flags: defaultMountFlags, - }, - { - Source: "mqueue", - Destination: "/dev/mqueue", - Device: "mqueue", - Flags: defaultMountFlags, - }, - { - Source: "sysfs", - Destination: "/sys", - Device: "sysfs", - Flags: defaultMountFlags | unix.MS_RDONLY, - }, - }, - UidMappings: []configs.IDMap{ - { - ContainerID: 0, - HostID: 1000, - Size: 65536, - }, - }, - GidMappings: []configs.IDMap{ - { - ContainerID: 0, - HostID: 1000, - Size: 65536, - }, - }, - Networks: []*configs.Network{ - { - Type: "loopback", - Address: "127.0.0.1/0", - Gateway: "localhost", - }, - }, - Rlimits: []configs.Rlimit{ - { - Type: unix.RLIMIT_NOFILE, - Hard: uint64(1025), - Soft: uint64(1025), - }, - }, -} -``` - -Once you have the configuration populated you can create a container: - -```go -container, err := factory.Create("container-id", config) -if err != nil { - logrus.Fatal(err) - return -} -``` - -To spawn bash as the initial process inside the container and have the -processes pid returned in order to wait, signal, or kill the process: - -```go -process := &libcontainer.Process{ - Args: []string{"/bin/bash"}, - Env: []string{"PATH=/bin"}, - User: "daemon", - Stdin: os.Stdin, - Stdout: os.Stdout, - Stderr: os.Stderr, - Init: true, -} - -err := container.Run(process) -if err != nil { - container.Destroy() - logrus.Fatal(err) - return -} - -// wait for the process to finish. -_, err := process.Wait() -if err != nil { - logrus.Fatal(err) -} - -// destroy the container. -container.Destroy() -``` - -Additional ways to interact with a running container are: - -```go -// return all the pids for all processes running inside the container. -processes, err := container.Processes() - -// get detailed cpu, memory, io, and network statistics for the container and -// it's processes. -stats, err := container.Stats() - -// pause all processes inside the container. -container.Pause() - -// resume all paused processes. -container.Resume() - -// send signal to container's init process. -container.Signal(signal) - -// update container resource constraints. -container.Set(config) - -// get current status of the container. -status, err := container.Status() - -// get current container's state information. -state, err := container.State() -``` - - -#### Checkpoint & Restore - -libcontainer now integrates [CRIU](http://criu.org/) for checkpointing and restoring containers. -This lets you save the state of a process running inside a container to disk, and then restore -that state into a new process, on the same machine or on another machine. - -`criu` version 1.5.2 or higher is required to use checkpoint and restore. -If you don't already have `criu` installed, you can build it from source, following the -[online instructions](http://criu.org/Installation). `criu` is also installed in the docker image -generated when building libcontainer with docker. - - -## Copyright and license - -Code and documentation copyright 2014 Docker, inc. -The code and documentation are released under the [Apache 2.0 license](../LICENSE). -The documentation is also released under Creative Commons Attribution 4.0 International License. -You may obtain a copy of the license, titled CC-BY-4.0, at http://creativecommons.org/licenses/by/4.0/. diff --git a/vendor/github.com/opencontainers/runc/libcontainer/SPEC.md b/vendor/github.com/opencontainers/runc/libcontainer/SPEC.md deleted file mode 100644 index 07ebdc12153..00000000000 --- a/vendor/github.com/opencontainers/runc/libcontainer/SPEC.md +++ /dev/null @@ -1,465 +0,0 @@ -## Container Specification - v1 - -This is the standard configuration for version 1 containers. It includes -namespaces, standard filesystem setup, a default Linux capability set, and -information about resource reservations. It also has information about any -populated environment settings for the processes running inside a container. - -Along with the configuration of how a container is created the standard also -discusses actions that can be performed on a container to manage and inspect -information about the processes running inside. - -The v1 profile is meant to be able to accommodate the majority of applications -with a strong security configuration. - -### System Requirements and Compatibility - -Minimum requirements: -* Kernel version - 3.10 recommended 2.6.2x minimum(with backported patches) -* Mounted cgroups with each subsystem in its own hierarchy - - -### Namespaces - -| Flag | Enabled | -| --------------- | ------- | -| CLONE_NEWPID | 1 | -| CLONE_NEWUTS | 1 | -| CLONE_NEWIPC | 1 | -| CLONE_NEWNET | 1 | -| CLONE_NEWNS | 1 | -| CLONE_NEWUSER | 1 | -| CLONE_NEWCGROUP | 1 | - -Namespaces are created for the container via the `unshare` syscall. - - -### Filesystem - -A root filesystem must be provided to a container for execution. The container -will use this root filesystem (rootfs) to jail and spawn processes inside where -the binaries and system libraries are local to that directory. Any binaries -to be executed must be contained within this rootfs. - -Mounts that happen inside the container are automatically cleaned up when the -container exits as the mount namespace is destroyed and the kernel will -unmount all the mounts that were setup within that namespace. - -For a container to execute properly there are certain filesystems that -are required to be mounted within the rootfs that the runtime will setup. - -| Path | Type | Flags | Data | -| ----------- | ------ | -------------------------------------- | ---------------------------------------- | -| /proc | proc | MS_NOEXEC,MS_NOSUID,MS_NODEV | | -| /dev | tmpfs | MS_NOEXEC,MS_STRICTATIME | mode=755 | -| /dev/shm | tmpfs | MS_NOEXEC,MS_NOSUID,MS_NODEV | mode=1777,size=65536k | -| /dev/mqueue | mqueue | MS_NOEXEC,MS_NOSUID,MS_NODEV | | -| /dev/pts | devpts | MS_NOEXEC,MS_NOSUID | newinstance,ptmxmode=0666,mode=620,gid=5 | -| /sys | sysfs | MS_NOEXEC,MS_NOSUID,MS_NODEV,MS_RDONLY | | - - -After a container's filesystems are mounted within the newly created -mount namespace `/dev` will need to be populated with a set of device nodes. -It is expected that a rootfs does not need to have any device nodes specified -for `/dev` within the rootfs as the container will setup the correct devices -that are required for executing a container's process. - -| Path | Mode | Access | -| ------------ | ---- | ---------- | -| /dev/null | 0666 | rwm | -| /dev/zero | 0666 | rwm | -| /dev/full | 0666 | rwm | -| /dev/tty | 0666 | rwm | -| /dev/random | 0666 | rwm | -| /dev/urandom | 0666 | rwm | - - -**ptmx** -`/dev/ptmx` will need to be a symlink to the host's `/dev/ptmx` within -the container. - -The use of a pseudo TTY is optional within a container and it should support both. -If a pseudo is provided to the container `/dev/console` will need to be -setup by binding the console in `/dev/` after it has been populated and mounted -in tmpfs. - -| Source | Destination | UID GID | Mode | Type | -| --------------- | ------------ | ------- | ---- | ---- | -| *pty host path* | /dev/console | 0 0 | 0600 | bind | - - -After `/dev/null` has been setup we check for any external links between -the container's io, STDIN, STDOUT, STDERR. If the container's io is pointing -to `/dev/null` outside the container we close and `dup2` the `/dev/null` -that is local to the container's rootfs. - - -After the container has `/proc` mounted a few standard symlinks are setup -within `/dev/` for the io. - -| Source | Destination | -| --------------- | ----------- | -| /proc/self/fd | /dev/fd | -| /proc/self/fd/0 | /dev/stdin | -| /proc/self/fd/1 | /dev/stdout | -| /proc/self/fd/2 | /dev/stderr | - -A `pivot_root` is used to change the root for the process, effectively -jailing the process inside the rootfs. - -```c -put_old = mkdir(...); -pivot_root(rootfs, put_old); -chdir("/"); -unmount(put_old, MS_DETACH); -rmdir(put_old); -``` - -For container's running with a rootfs inside `ramfs` a `MS_MOVE` combined -with a `chroot` is required as `pivot_root` is not supported in `ramfs`. - -```c -mount(rootfs, "/", NULL, MS_MOVE, NULL); -chroot("."); -chdir("/"); -``` - -The `umask` is set back to `0022` after the filesystem setup has been completed. - -### Resources - -Cgroups are used to handle resource allocation for containers. This includes -system resources like cpu, memory, and device access. - -| Subsystem | Enabled | -| ---------- | ------- | -| devices | 1 | -| memory | 1 | -| cpu | 1 | -| cpuacct | 1 | -| cpuset | 1 | -| blkio | 1 | -| perf_event | 1 | -| freezer | 1 | -| hugetlb | 1 | -| pids | 1 | - - -All cgroup subsystem are joined so that statistics can be collected from -each of the subsystems. Freezer does not expose any stats but is joined -so that containers can be paused and resumed. - -The parent process of the container's init must place the init pid inside -the correct cgroups before the initialization begins. This is done so -that no processes or threads escape the cgroups. This sync is -done via a pipe ( specified in the runtime section below ) that the container's -init process will block waiting for the parent to finish setup. - -### IntelRdt - -Intel platforms with new Xeon CPU support Resource Director Technology (RDT). -Cache Allocation Technology (CAT) and Memory Bandwidth Allocation (MBA) are -two sub-features of RDT. - -Cache Allocation Technology (CAT) provides a way for the software to restrict -cache allocation to a defined 'subset' of L3 cache which may be overlapping -with other 'subsets'. The different subsets are identified by class of -service (CLOS) and each CLOS has a capacity bitmask (CBM). - -Memory Bandwidth Allocation (MBA) provides indirect and approximate throttle -over memory bandwidth for the software. A user controls the resource by -indicating the percentage of maximum memory bandwidth or memory bandwidth limit -in MBps unit if MBA Software Controller is enabled. - -It can be used to handle L3 cache and memory bandwidth resources allocation -for containers if hardware and kernel support Intel RDT CAT and MBA features. - -In Linux 4.10 kernel or newer, the interface is defined and exposed via -"resource control" filesystem, which is a "cgroup-like" interface. - -Comparing with cgroups, it has similar process management lifecycle and -interfaces in a container. But unlike cgroups' hierarchy, it has single level -filesystem layout. - -CAT and MBA features are introduced in Linux 4.10 and 4.12 kernel via -"resource control" filesystem. - -Intel RDT "resource control" filesystem hierarchy: -``` -mount -t resctrl resctrl /sys/fs/resctrl -tree /sys/fs/resctrl -/sys/fs/resctrl/ -|-- info -| |-- L3 -| | |-- cbm_mask -| | |-- min_cbm_bits -| | |-- num_closids -| |-- MB -| |-- bandwidth_gran -| |-- delay_linear -| |-- min_bandwidth -| |-- num_closids -|-- ... -|-- schemata -|-- tasks -|-- - |-- ... - |-- schemata - |-- tasks -``` - -For runc, we can make use of `tasks` and `schemata` configuration for L3 -cache and memory bandwidth resources constraints. - -The file `tasks` has a list of tasks that belongs to this group (e.g., -" group). Tasks can be added to a group by writing the task ID -to the "tasks" file (which will automatically remove them from the previous -group to which they belonged). New tasks created by fork(2) and clone(2) are -added to the same group as their parent. - -The file `schemata` has a list of all the resources available to this group. -Each resource (L3 cache, memory bandwidth) has its own line and format. - -L3 cache schema: -It has allocation bitmasks/values for L3 cache on each socket, which -contains L3 cache id and capacity bitmask (CBM). -``` - Format: "L3:=;=;..." -``` -For example, on a two-socket machine, the schema line could be "L3:0=ff;1=c0" -which means L3 cache id 0's CBM is 0xff, and L3 cache id 1's CBM is 0xc0. - -The valid L3 cache CBM is a *contiguous bits set* and number of bits that can -be set is less than the max bit. The max bits in the CBM is varied among -supported Intel CPU models. Kernel will check if it is valid when writing. -e.g., default value 0xfffff in root indicates the max bits of CBM is 20 -bits, which mapping to entire L3 cache capacity. Some valid CBM values to -set in a group: 0xf, 0xf0, 0x3ff, 0x1f00 and etc. - -Memory bandwidth schema: -It has allocation values for memory bandwidth on each socket, which contains -L3 cache id and memory bandwidth. -``` - Format: "MB:=bandwidth0;=bandwidth1;..." -``` -For example, on a two-socket machine, the schema line could be "MB:0=20;1=70" - -The minimum bandwidth percentage value for each CPU model is predefined and -can be looked up through "info/MB/min_bandwidth". The bandwidth granularity -that is allocated is also dependent on the CPU model and can be looked up at -"info/MB/bandwidth_gran". The available bandwidth control steps are: -min_bw + N * bw_gran. Intermediate values are rounded to the next control -step available on the hardware. - -If MBA Software Controller is enabled through mount option "-o mba_MBps" -mount -t resctrl resctrl -o mba_MBps /sys/fs/resctrl -We could specify memory bandwidth in "MBps" (Mega Bytes per second) unit -instead of "percentages". The kernel underneath would use a software feedback -mechanism or a "Software Controller" which reads the actual bandwidth using -MBM counters and adjust the memory bandwidth percentages to ensure: -"actual memory bandwidth < user specified memory bandwidth". - -For example, on a two-socket machine, the schema line could be -"MB:0=5000;1=7000" which means 5000 MBps memory bandwidth limit on socket 0 -and 7000 MBps memory bandwidth limit on socket 1. - -For more information about Intel RDT kernel interface: -https://www.kernel.org/doc/Documentation/x86/intel_rdt_ui.txt - -``` -An example for runc: -Consider a two-socket machine with two L3 caches where the default CBM is -0x7ff and the max CBM length is 11 bits, and minimum memory bandwidth of 10% -with a memory bandwidth granularity of 10%. - -Tasks inside the container only have access to the "upper" 7/11 of L3 cache -on socket 0 and the "lower" 5/11 L3 cache on socket 1, and may use a -maximum memory bandwidth of 20% on socket 0 and 70% on socket 1. - -"linux": { - "intelRdt": { - "closID": "guaranteed_group", - "l3CacheSchema": "L3:0=7f0;1=1f", - "memBwSchema": "MB:0=20;1=70" - } -} -``` - -### Security - -The standard set of Linux capabilities that are set in a container -provide a good default for security and flexibility for the applications. - - -| Capability | Enabled | -| -------------------- | ------- | -| CAP_NET_RAW | 1 | -| CAP_NET_BIND_SERVICE | 1 | -| CAP_AUDIT_READ | 1 | -| CAP_AUDIT_WRITE | 1 | -| CAP_DAC_OVERRIDE | 1 | -| CAP_SETFCAP | 1 | -| CAP_SETPCAP | 1 | -| CAP_SETGID | 1 | -| CAP_SETUID | 1 | -| CAP_MKNOD | 1 | -| CAP_CHOWN | 1 | -| CAP_FOWNER | 1 | -| CAP_FSETID | 1 | -| CAP_KILL | 1 | -| CAP_SYS_CHROOT | 1 | -| CAP_NET_BROADCAST | 0 | -| CAP_SYS_MODULE | 0 | -| CAP_SYS_RAWIO | 0 | -| CAP_SYS_PACCT | 0 | -| CAP_SYS_ADMIN | 0 | -| CAP_SYS_NICE | 0 | -| CAP_SYS_RESOURCE | 0 | -| CAP_SYS_TIME | 0 | -| CAP_SYS_TTY_CONFIG | 0 | -| CAP_AUDIT_CONTROL | 0 | -| CAP_MAC_OVERRIDE | 0 | -| CAP_MAC_ADMIN | 0 | -| CAP_NET_ADMIN | 0 | -| CAP_SYSLOG | 0 | -| CAP_DAC_READ_SEARCH | 0 | -| CAP_LINUX_IMMUTABLE | 0 | -| CAP_IPC_LOCK | 0 | -| CAP_IPC_OWNER | 0 | -| CAP_SYS_PTRACE | 0 | -| CAP_SYS_BOOT | 0 | -| CAP_LEASE | 0 | -| CAP_WAKE_ALARM | 0 | -| CAP_BLOCK_SUSPEND | 0 | - - -Additional security layers like [apparmor](https://wiki.ubuntu.com/AppArmor) -and [selinux](http://selinuxproject.org/page/Main_Page) can be used with -the containers. A container should support setting an apparmor profile or -selinux process and mount labels if provided in the configuration. - -Standard apparmor profile: -```c -#include -profile flags=(attach_disconnected,mediate_deleted) { - #include - network, - capability, - file, - umount, - - deny @{PROC}/sys/fs/** wklx, - deny @{PROC}/sysrq-trigger rwklx, - deny @{PROC}/mem rwklx, - deny @{PROC}/kmem rwklx, - deny @{PROC}/sys/kernel/[^s][^h][^m]* wklx, - deny @{PROC}/sys/kernel/*/** wklx, - - deny mount, - - deny /sys/[^f]*/** wklx, - deny /sys/f[^s]*/** wklx, - deny /sys/fs/[^c]*/** wklx, - deny /sys/fs/c[^g]*/** wklx, - deny /sys/fs/cg[^r]*/** wklx, - deny /sys/firmware/efi/efivars/** rwklx, - deny /sys/kernel/security/** rwklx, -} -``` - -*TODO: seccomp work is being done to find a good default config* - -### Runtime and Init Process - -During container creation the parent process needs to talk to the container's init -process and have a form of synchronization. This is accomplished by creating -a pipe that is passed to the container's init. When the init process first spawns -it will block on its side of the pipe until the parent closes its side. This -allows the parent to have time to set the new process inside a cgroup hierarchy -and/or write any uid/gid mappings required for user namespaces. -The pipe is passed to the init process via FD 3. - -The application consuming libcontainer should be compiled statically. libcontainer -does not define any init process and the arguments provided are used to `exec` the -process inside the application. There should be no long running init within the -container spec. - -If a pseudo tty is provided to a container it will open and `dup2` the console -as the container's STDIN, STDOUT, STDERR as well as mounting the console -as `/dev/console`. - -An extra set of mounts are provided to a container and setup for use. A container's -rootfs can contain some non portable files inside that can cause side effects during -execution of a process. These files are usually created and populated with the container -specific information via the runtime. - -**Extra runtime files:** -* /etc/hosts -* /etc/resolv.conf -* /etc/hostname -* /etc/localtime - - -#### Defaults - -There are a few defaults that can be overridden by users, but in their omission -these apply to processes within a container. - -| Type | Value | -| ------------------- | ------------------------------ | -| Parent Death Signal | SIGKILL | -| UID | 0 | -| GID | 0 | -| GROUPS | 0, NULL | -| CWD | "/" | -| $HOME | Current user's home dir or "/" | -| Readonly rootfs | false | -| Pseudo TTY | false | - - -## Actions - -After a container is created there is a standard set of actions that can -be done to the container. These actions are part of the public API for -a container. - -| Action | Description | -| -------------- | ------------------------------------------------------------------ | -| Get processes | Return all the pids for processes running inside a container | -| Get Stats | Return resource statistics for the container as a whole | -| Wait | Waits on the container's init process ( pid 1 ) | -| Wait Process | Wait on any of the container's processes returning the exit status | -| Destroy | Kill the container's init process and remove any filesystem state | -| Signal | Send a signal to the container's init process | -| Signal Process | Send a signal to any of the container's processes | -| Pause | Pause all processes inside the container | -| Resume | Resume all processes inside the container if paused | -| Exec | Execute a new process inside of the container ( requires setns ) | -| Set | Setup configs of the container after it's created | - -### Execute a new process inside of a running container - -User can execute a new process inside of a running container. Any binaries to be -executed must be accessible within the container's rootfs. - -The started process will run inside the container's rootfs. Any changes -made by the process to the container's filesystem will persist after the -process finished executing. - -The started process will join all the container's existing namespaces. When the -container is paused, the process will also be paused and will resume when -the container is unpaused. The started process will only run when the container's -primary process (PID 1) is running, and will not be restarted when the container -is restarted. - -#### Planned additions - -The started process will have its own cgroups nested inside the container's -cgroups. This is used for process tracking and optionally resource allocation -handling for the new process. Freezer cgroup is required, the rest of the cgroups -are optional. The process executor must place its pid inside the correct -cgroups before starting the process. This is done so that no child processes or -threads can escape the cgroups. - -When the process is stopped, the process executor will try (in a best-effort way) -to stop all its children and remove the sub-cgroups. diff --git a/vendor/github.com/opencontainers/runc/libcontainer/apparmor/apparmor.go b/vendor/github.com/opencontainers/runc/libcontainer/apparmor/apparmor.go deleted file mode 100644 index 4b03d4c715c..00000000000 --- a/vendor/github.com/opencontainers/runc/libcontainer/apparmor/apparmor.go +++ /dev/null @@ -1,16 +0,0 @@ -package apparmor - -import "errors" - -var ( - // IsEnabled returns true if apparmor is enabled for the host. - IsEnabled = isEnabled - - // ApplyProfile will apply the profile with the specified name to the process after - // the next exec. It is only supported on Linux and produces an ErrApparmorNotEnabled - // on other platforms. - ApplyProfile = applyProfile - - // ErrApparmorNotEnabled indicates that AppArmor is not enabled or not supported. - ErrApparmorNotEnabled = errors.New("apparmor: config provided but apparmor not supported") -) diff --git a/vendor/github.com/opencontainers/runc/libcontainer/apparmor/apparmor_linux.go b/vendor/github.com/opencontainers/runc/libcontainer/apparmor/apparmor_linux.go deleted file mode 100644 index 8b1483c7de7..00000000000 --- a/vendor/github.com/opencontainers/runc/libcontainer/apparmor/apparmor_linux.go +++ /dev/null @@ -1,68 +0,0 @@ -package apparmor - -import ( - "errors" - "fmt" - "os" - "sync" - - "github.com/opencontainers/runc/libcontainer/utils" -) - -var ( - appArmorEnabled bool - checkAppArmor sync.Once -) - -// isEnabled returns true if apparmor is enabled for the host. -func isEnabled() bool { - checkAppArmor.Do(func() { - if _, err := os.Stat("/sys/kernel/security/apparmor"); err == nil { - buf, err := os.ReadFile("/sys/module/apparmor/parameters/enabled") - appArmorEnabled = err == nil && len(buf) > 1 && buf[0] == 'Y' - } - }) - return appArmorEnabled -} - -func setProcAttr(attr, value string) error { - // Under AppArmor you can only change your own attr, so use /proc/self/ - // instead of /proc// like libapparmor does - attrPath := "/proc/self/attr/apparmor/" + attr - if _, err := os.Stat(attrPath); errors.Is(err, os.ErrNotExist) { - // fall back to the old convention - attrPath = "/proc/self/attr/" + attr - } - - f, err := os.OpenFile(attrPath, os.O_WRONLY, 0) - if err != nil { - return err - } - defer f.Close() - - if err := utils.EnsureProcHandle(f); err != nil { - return err - } - - _, err = f.WriteString(value) - return err -} - -// changeOnExec reimplements aa_change_onexec from libapparmor in Go -func changeOnExec(name string) error { - if err := setProcAttr("exec", "exec "+name); err != nil { - return fmt.Errorf("apparmor failed to apply profile: %w", err) - } - return nil -} - -// applyProfile will apply the profile with the specified name to the process after -// the next exec. It is only supported on Linux and produces an error on other -// platforms. -func applyProfile(name string) error { - if name == "" { - return nil - } - - return changeOnExec(name) -} diff --git a/vendor/github.com/opencontainers/runc/libcontainer/apparmor/apparmor_unsupported.go b/vendor/github.com/opencontainers/runc/libcontainer/apparmor/apparmor_unsupported.go deleted file mode 100644 index 684248f2559..00000000000 --- a/vendor/github.com/opencontainers/runc/libcontainer/apparmor/apparmor_unsupported.go +++ /dev/null @@ -1,15 +0,0 @@ -//go:build !linux -// +build !linux - -package apparmor - -func isEnabled() bool { - return false -} - -func applyProfile(name string) error { - if name != "" { - return ErrApparmorNotEnabled - } - return nil -} diff --git a/vendor/github.com/opencontainers/runc/libcontainer/capabilities/capabilities.go b/vendor/github.com/opencontainers/runc/libcontainer/capabilities/capabilities.go deleted file mode 100644 index d38b8a7cd89..00000000000 --- a/vendor/github.com/opencontainers/runc/libcontainer/capabilities/capabilities.go +++ /dev/null @@ -1,123 +0,0 @@ -//go:build linux -// +build linux - -package capabilities - -import ( - "sort" - "strings" - - "github.com/opencontainers/runc/libcontainer/configs" - "github.com/sirupsen/logrus" - "github.com/syndtr/gocapability/capability" -) - -const allCapabilityTypes = capability.CAPS | capability.BOUNDING | capability.AMBIENT - -var ( - capabilityMap map[string]capability.Cap - capTypes = []capability.CapType{ - capability.BOUNDING, - capability.PERMITTED, - capability.INHERITABLE, - capability.EFFECTIVE, - capability.AMBIENT, - } -) - -func init() { - capabilityMap = make(map[string]capability.Cap, capability.CAP_LAST_CAP+1) - for _, c := range capability.List() { - if c > capability.CAP_LAST_CAP { - continue - } - capabilityMap["CAP_"+strings.ToUpper(c.String())] = c - } -} - -// KnownCapabilities returns the list of the known capabilities. -// Used by `runc features`. -func KnownCapabilities() []string { - list := capability.List() - res := make([]string, len(list)) - for i, c := range list { - res[i] = "CAP_" + strings.ToUpper(c.String()) - } - return res -} - -// New creates a new Caps from the given Capabilities config. Unknown Capabilities -// or Capabilities that are unavailable in the current environment are ignored, -// printing a warning instead. -func New(capConfig *configs.Capabilities) (*Caps, error) { - var ( - err error - c Caps - ) - - unknownCaps := make(map[string]struct{}) - c.caps = map[capability.CapType][]capability.Cap{ - capability.BOUNDING: capSlice(capConfig.Bounding, unknownCaps), - capability.EFFECTIVE: capSlice(capConfig.Effective, unknownCaps), - capability.INHERITABLE: capSlice(capConfig.Inheritable, unknownCaps), - capability.PERMITTED: capSlice(capConfig.Permitted, unknownCaps), - capability.AMBIENT: capSlice(capConfig.Ambient, unknownCaps), - } - if c.pid, err = capability.NewPid2(0); err != nil { - return nil, err - } - if err = c.pid.Load(); err != nil { - return nil, err - } - if len(unknownCaps) > 0 { - logrus.Warn("ignoring unknown or unavailable capabilities: ", mapKeys(unknownCaps)) - } - return &c, nil -} - -// capSlice converts the slice of capability names in caps, to their numeric -// equivalent, and returns them as a slice. Unknown or unavailable capabilities -// are not returned, but appended to unknownCaps. -func capSlice(caps []string, unknownCaps map[string]struct{}) []capability.Cap { - var out []capability.Cap - for _, c := range caps { - if v, ok := capabilityMap[c]; !ok { - unknownCaps[c] = struct{}{} - } else { - out = append(out, v) - } - } - return out -} - -// mapKeys returns the keys of input in sorted order -func mapKeys(input map[string]struct{}) []string { - var keys []string - for c := range input { - keys = append(keys, c) - } - sort.Strings(keys) - return keys -} - -// Caps holds the capabilities for a container. -type Caps struct { - pid capability.Capabilities - caps map[capability.CapType][]capability.Cap -} - -// ApplyBoundingSet sets the capability bounding set to those specified in the whitelist. -func (c *Caps) ApplyBoundingSet() error { - c.pid.Clear(capability.BOUNDING) - c.pid.Set(capability.BOUNDING, c.caps[capability.BOUNDING]...) - return c.pid.Apply(capability.BOUNDING) -} - -// Apply sets all the capabilities for the current process in the config. -func (c *Caps) ApplyCaps() error { - c.pid.Clear(allCapabilityTypes) - for _, g := range capTypes { - c.pid.Set(g, c.caps[g]...) - } - return c.pid.Apply(allCapabilityTypes) -} diff --git a/vendor/github.com/opencontainers/runc/libcontainer/capabilities/capabilities_unsupported.go b/vendor/github.com/opencontainers/runc/libcontainer/capabilities/capabilities_unsupported.go deleted file mode 100644 index 0eafa4f2c2c..00000000000 --- a/vendor/github.com/opencontainers/runc/libcontainer/capabilities/capabilities_unsupported.go +++ /dev/null @@ -1,4 +0,0 @@ -//go:build !linux -// +build !linux - -package capabilities diff --git a/vendor/github.com/opencontainers/runc/libcontainer/configs/validate/rootless.go b/vendor/github.com/opencontainers/runc/libcontainer/configs/validate/rootless.go deleted file mode 100644 index 37c383366fe..00000000000 --- a/vendor/github.com/opencontainers/runc/libcontainer/configs/validate/rootless.go +++ /dev/null @@ -1,86 +0,0 @@ -package validate - -import ( - "errors" - "fmt" - "strings" - - "github.com/opencontainers/runc/libcontainer/configs" -) - -// rootlessEUID makes sure that the config can be applied when runc -// is being executed as a non-root user (euid != 0) in the current user namespace. -func (v *ConfigValidator) rootlessEUID(config *configs.Config) error { - if !config.RootlessEUID { - return nil - } - if err := rootlessEUIDMappings(config); err != nil { - return err - } - if err := rootlessEUIDMount(config); err != nil { - return err - } - - // XXX: We currently can't verify the user config at all, because - // configs.Config doesn't store the user-related configs. So this - // has to be verified by setupUser() in init_linux.go. - - return nil -} - -func rootlessEUIDMappings(config *configs.Config) error { - if !config.Namespaces.Contains(configs.NEWUSER) { - return errors.New("rootless container requires user namespaces") - } - // We only require mappings if we are not joining another userns. - if path := config.Namespaces.PathOf(configs.NEWUSER); path == "" { - if len(config.UidMappings) == 0 { - return errors.New("rootless containers requires at least one UID mapping") - } - if len(config.GidMappings) == 0 { - return errors.New("rootless containers requires at least one GID mapping") - } - } - return nil -} - -// mount verifies that the user isn't trying to set up any mounts they don't have -// the rights to do. In addition, it makes sure that no mount has a `uid=` or -// `gid=` option that doesn't resolve to root. -func rootlessEUIDMount(config *configs.Config) error { - // XXX: We could whitelist allowed devices at this point, but I'm not - // convinced that's a good idea. The kernel is the best arbiter of - // access control. - - for _, mount := range config.Mounts { - // Check that the options list doesn't contain any uid= or gid= entries - // that don't resolve to root. - for _, opt := range strings.Split(mount.Data, ",") { - if strings.HasPrefix(opt, "uid=") { - var uid int - n, err := fmt.Sscanf(opt, "uid=%d", &uid) - if n != 1 || err != nil { - // Ignore unknown mount options. - continue - } - if _, err := config.HostUID(uid); err != nil { - return fmt.Errorf("cannot specify uid=%d mount option for rootless container: %w", uid, err) - } - } - - if strings.HasPrefix(opt, "gid=") { - var gid int - n, err := fmt.Sscanf(opt, "gid=%d", &gid) - if n != 1 || err != nil { - // Ignore unknown mount options. - continue - } - if _, err := config.HostGID(gid); err != nil { - return fmt.Errorf("cannot specify gid=%d mount option for rootless container: %w", gid, err) - } - } - } - } - - return nil -} diff --git a/vendor/github.com/opencontainers/runc/libcontainer/configs/validate/validator.go b/vendor/github.com/opencontainers/runc/libcontainer/configs/validate/validator.go deleted file mode 100644 index ece70a45d31..00000000000 --- a/vendor/github.com/opencontainers/runc/libcontainer/configs/validate/validator.go +++ /dev/null @@ -1,306 +0,0 @@ -package validate - -import ( - "errors" - "fmt" - "os" - "path/filepath" - "strings" - "sync" - - "github.com/opencontainers/runc/libcontainer/cgroups" - "github.com/opencontainers/runc/libcontainer/configs" - "github.com/opencontainers/runc/libcontainer/intelrdt" - selinux "github.com/opencontainers/selinux/go-selinux" - "github.com/sirupsen/logrus" - "golang.org/x/sys/unix" -) - -type Validator interface { - Validate(*configs.Config) error -} - -func New() Validator { - return &ConfigValidator{} -} - -type ConfigValidator struct{} - -type check func(config *configs.Config) error - -func (v *ConfigValidator) Validate(config *configs.Config) error { - checks := []check{ - v.cgroups, - v.rootfs, - v.network, - v.hostname, - v.security, - v.usernamespace, - v.cgroupnamespace, - v.sysctl, - v.intelrdt, - v.rootlessEUID, - } - for _, c := range checks { - if err := c(config); err != nil { - return err - } - } - // Relaxed validation rules for backward compatibility - warns := []check{ - v.mounts, // TODO (runc v1.x.x): make this an error instead of a warning - } - for _, c := range warns { - if err := c(config); err != nil { - logrus.WithError(err).Warn("invalid configuration") - } - } - return nil -} - -// rootfs validates if the rootfs is an absolute path and is not a symlink -// to the container's root filesystem. -func (v *ConfigValidator) rootfs(config *configs.Config) error { - if _, err := os.Stat(config.Rootfs); err != nil { - return fmt.Errorf("invalid rootfs: %w", err) - } - cleaned, err := filepath.Abs(config.Rootfs) - if err != nil { - return fmt.Errorf("invalid rootfs: %w", err) - } - if cleaned, err = filepath.EvalSymlinks(cleaned); err != nil { - return fmt.Errorf("invalid rootfs: %w", err) - } - if filepath.Clean(config.Rootfs) != cleaned { - return errors.New("invalid rootfs: not an absolute path, or a symlink") - } - return nil -} - -func (v *ConfigValidator) network(config *configs.Config) error { - if !config.Namespaces.Contains(configs.NEWNET) { - if len(config.Networks) > 0 || len(config.Routes) > 0 { - return errors.New("unable to apply network settings without a private NET namespace") - } - } - return nil -} - -func (v *ConfigValidator) hostname(config *configs.Config) error { - if config.Hostname != "" && !config.Namespaces.Contains(configs.NEWUTS) { - return errors.New("unable to set hostname without a private UTS namespace") - } - return nil -} - -func (v *ConfigValidator) security(config *configs.Config) error { - // restrict sys without mount namespace - if (len(config.MaskPaths) > 0 || len(config.ReadonlyPaths) > 0) && - !config.Namespaces.Contains(configs.NEWNS) { - return errors.New("unable to restrict sys entries without a private MNT namespace") - } - if config.ProcessLabel != "" && !selinux.GetEnabled() { - return errors.New("selinux label is specified in config, but selinux is disabled or not supported") - } - - return nil -} - -func (v *ConfigValidator) usernamespace(config *configs.Config) error { - if config.Namespaces.Contains(configs.NEWUSER) { - if _, err := os.Stat("/proc/self/ns/user"); os.IsNotExist(err) { - return errors.New("user namespaces aren't enabled in the kernel") - } - hasPath := config.Namespaces.PathOf(configs.NEWUSER) != "" - hasMappings := config.UidMappings != nil || config.GidMappings != nil - if !hasPath && !hasMappings { - return errors.New("user namespaces enabled, but no namespace path to join nor mappings to apply specified") - } - // The hasPath && hasMappings validation case is handled in specconv -- - // we cache the mappings in Config during specconv in the hasPath case, - // so we cannot do that validation here. - } else { - if config.UidMappings != nil || config.GidMappings != nil { - return errors.New("user namespace mappings specified, but user namespace isn't enabled in the config") - } - } - return nil -} - -func (v *ConfigValidator) cgroupnamespace(config *configs.Config) error { - if config.Namespaces.Contains(configs.NEWCGROUP) { - if _, err := os.Stat("/proc/self/ns/cgroup"); os.IsNotExist(err) { - return errors.New("cgroup namespaces aren't enabled in the kernel") - } - } - return nil -} - -// convertSysctlVariableToDotsSeparator can return sysctl variables in dots separator format. -// The '/' separator is also accepted in place of a '.'. -// Convert the sysctl variables to dots separator format for validation. -// More info: sysctl(8), sysctl.d(5). -// -// For example: -// Input sysctl variable "net/ipv4/conf/eno2.100.rp_filter" -// will return the converted value "net.ipv4.conf.eno2/100.rp_filter" -func convertSysctlVariableToDotsSeparator(val string) string { - if val == "" { - return val - } - firstSepIndex := strings.IndexAny(val, "./") - if firstSepIndex == -1 || val[firstSepIndex] == '.' { - return val - } - - f := func(r rune) rune { - switch r { - case '.': - return '/' - case '/': - return '.' - } - return r - } - return strings.Map(f, val) -} - -// sysctl validates that the specified sysctl keys are valid or not. -// /proc/sys isn't completely namespaced and depending on which namespaces -// are specified, a subset of sysctls are permitted. -func (v *ConfigValidator) sysctl(config *configs.Config) error { - validSysctlMap := map[string]bool{ - "kernel.msgmax": true, - "kernel.msgmnb": true, - "kernel.msgmni": true, - "kernel.sem": true, - "kernel.shmall": true, - "kernel.shmmax": true, - "kernel.shmmni": true, - "kernel.shm_rmid_forced": true, - } - - var ( - netOnce sync.Once - hostnet bool - hostnetErr error - ) - - for s := range config.Sysctl { - s := convertSysctlVariableToDotsSeparator(s) - if validSysctlMap[s] || strings.HasPrefix(s, "fs.mqueue.") { - if config.Namespaces.Contains(configs.NEWIPC) { - continue - } else { - return fmt.Errorf("sysctl %q is not allowed in the hosts ipc namespace", s) - } - } - if strings.HasPrefix(s, "net.") { - // Is container using host netns? - // Here "host" means "current", not "initial". - netOnce.Do(func() { - if !config.Namespaces.Contains(configs.NEWNET) { - hostnet = true - return - } - path := config.Namespaces.PathOf(configs.NEWNET) - if path == "" { - // own netns, so hostnet = false - return - } - hostnet, hostnetErr = isHostNetNS(path) - }) - if hostnetErr != nil { - return fmt.Errorf("invalid netns path: %w", hostnetErr) - } - if hostnet { - return fmt.Errorf("sysctl %q not allowed in host network namespace", s) - } - continue - } - if config.Namespaces.Contains(configs.NEWUTS) { - switch s { - case "kernel.domainname": - // This is namespaced and there's no explicit OCI field for it. - continue - case "kernel.hostname": - // This is namespaced but there's a conflicting (dedicated) OCI field for it. - return fmt.Errorf("sysctl %q is not allowed as it conflicts with the OCI %q field", s, "hostname") - } - } - return fmt.Errorf("sysctl %q is not in a separate kernel namespace", s) - } - - return nil -} - -func (v *ConfigValidator) intelrdt(config *configs.Config) error { - if config.IntelRdt != nil { - if config.IntelRdt.ClosID == "." || config.IntelRdt.ClosID == ".." || strings.Contains(config.IntelRdt.ClosID, "/") { - return fmt.Errorf("invalid intelRdt.ClosID %q", config.IntelRdt.ClosID) - } - - if !intelrdt.IsCATEnabled() && config.IntelRdt.L3CacheSchema != "" { - return errors.New("intelRdt.l3CacheSchema is specified in config, but Intel RDT/CAT is not enabled") - } - if !intelrdt.IsMBAEnabled() && config.IntelRdt.MemBwSchema != "" { - return errors.New("intelRdt.memBwSchema is specified in config, but Intel RDT/MBA is not enabled") - } - } - - return nil -} - -func (v *ConfigValidator) cgroups(config *configs.Config) error { - c := config.Cgroups - if c == nil { - return nil - } - - if (c.Name != "" || c.Parent != "") && c.Path != "" { - return fmt.Errorf("cgroup: either Path or Name and Parent should be used, got %+v", c) - } - - r := c.Resources - if r == nil { - return nil - } - - if !cgroups.IsCgroup2UnifiedMode() && r.Unified != nil { - return cgroups.ErrV1NoUnified - } - - if cgroups.IsCgroup2UnifiedMode() { - _, err := cgroups.ConvertMemorySwapToCgroupV2Value(r.MemorySwap, r.Memory) - if err != nil { - return err - } - } - - return nil -} - -func (v *ConfigValidator) mounts(config *configs.Config) error { - for _, m := range config.Mounts { - if !filepath.IsAbs(m.Destination) { - return fmt.Errorf("invalid mount %+v: mount destination not absolute", m) - } - } - - return nil -} - -func isHostNetNS(path string) (bool, error) { - const currentProcessNetns = "/proc/self/ns/net" - - var st1, st2 unix.Stat_t - - if err := unix.Stat(currentProcessNetns, &st1); err != nil { - return false, &os.PathError{Op: "stat", Path: currentProcessNetns, Err: err} - } - if err := unix.Stat(path, &st2); err != nil { - return false, &os.PathError{Op: "stat", Path: path, Err: err} - } - - return (st1.Dev == st2.Dev) && (st1.Ino == st2.Ino), nil -} diff --git a/vendor/github.com/opencontainers/runc/libcontainer/console_linux.go b/vendor/github.com/opencontainers/runc/libcontainer/console_linux.go deleted file mode 100644 index 29b9c3b0897..00000000000 --- a/vendor/github.com/opencontainers/runc/libcontainer/console_linux.go +++ /dev/null @@ -1,41 +0,0 @@ -package libcontainer - -import ( - "os" - - "golang.org/x/sys/unix" -) - -// mount initializes the console inside the rootfs mounting with the specified mount label -// and applying the correct ownership of the console. -func mountConsole(slavePath string) error { - oldMask := unix.Umask(0o000) - defer unix.Umask(oldMask) - f, err := os.Create("/dev/console") - if err != nil && !os.IsExist(err) { - return err - } - if f != nil { - f.Close() - } - return mount(slavePath, "/dev/console", "", "bind", unix.MS_BIND, "") -} - -// dupStdio opens the slavePath for the console and dups the fds to the current -// processes stdio, fd 0,1,2. -func dupStdio(slavePath string) error { - fd, err := unix.Open(slavePath, unix.O_RDWR, 0) - if err != nil { - return &os.PathError{ - Op: "open", - Path: slavePath, - Err: err, - } - } - for _, i := range []int{0, 1, 2} { - if err := unix.Dup3(fd, i, 0); err != nil { - return err - } - } - return nil -} diff --git a/vendor/github.com/opencontainers/runc/libcontainer/container.go b/vendor/github.com/opencontainers/runc/libcontainer/container.go deleted file mode 100644 index 300c9526cf9..00000000000 --- a/vendor/github.com/opencontainers/runc/libcontainer/container.go +++ /dev/null @@ -1,130 +0,0 @@ -// Package libcontainer provides a native Go implementation for creating containers -// with namespaces, cgroups, capabilities, and filesystem access controls. -// It allows you to manage the lifecycle of the container performing additional operations -// after the container is created. -package libcontainer - -import ( - "os" - "time" - - "github.com/opencontainers/runc/libcontainer/configs" - "github.com/opencontainers/runtime-spec/specs-go" -) - -// Status is the status of a container. -type Status int - -const ( - // Created is the status that denotes the container exists but has not been run yet. - Created Status = iota - // Running is the status that denotes the container exists and is running. - Running - // Pausing is the status that denotes the container exists, it is in the process of being paused. - Pausing - // Paused is the status that denotes the container exists, but all its processes are paused. - Paused - // Stopped is the status that denotes the container does not have a created or running process. - Stopped -) - -func (s Status) String() string { - switch s { - case Created: - return "created" - case Running: - return "running" - case Pausing: - return "pausing" - case Paused: - return "paused" - case Stopped: - return "stopped" - default: - return "unknown" - } -} - -// BaseState represents the platform agnostic pieces relating to a -// running container's state -type BaseState struct { - // ID is the container ID. - ID string `json:"id"` - - // InitProcessPid is the init process id in the parent namespace. - InitProcessPid int `json:"init_process_pid"` - - // InitProcessStartTime is the init process start time in clock cycles since boot time. - InitProcessStartTime uint64 `json:"init_process_start"` - - // Created is the unix timestamp for the creation time of the container in UTC - Created time.Time `json:"created"` - - // Config is the container's configuration. - Config configs.Config `json:"config"` -} - -// BaseContainer is a libcontainer container object. -// -// Each container is thread-safe within the same process. Since a container can -// be destroyed by a separate process, any function may return that the container -// was not found. BaseContainer includes methods that are platform agnostic. -type BaseContainer interface { - // Returns the ID of the container - ID() string - - // Returns the current status of the container. - Status() (Status, error) - - // State returns the current container's state information. - State() (*State, error) - - // OCIState returns the current container's state information. - OCIState() (*specs.State, error) - - // Returns the current config of the container. - Config() configs.Config - - // Returns the PIDs inside this container. The PIDs are in the namespace of the calling process. - // - // Some of the returned PIDs may no longer refer to processes in the Container, unless - // the Container state is PAUSED in which case every PID in the slice is valid. - Processes() ([]int, error) - - // Returns statistics for the container. - Stats() (*Stats, error) - - // Set resources of container as configured - // - // We can use this to change resources when containers are running. - // - Set(config configs.Config) error - - // Start a process inside the container. Returns error if process fails to - // start. You can track process lifecycle with passed Process structure. - Start(process *Process) (err error) - - // Run immediately starts the process inside the container. Returns error if process - // fails to start. It does not block waiting for the exec fifo after start returns but - // opens the fifo after start returns. - Run(process *Process) (err error) - - // Destroys the container, if its in a valid state, after killing any - // remaining running processes. - // - // Any event registrations are removed before the container is destroyed. - // No error is returned if the container is already destroyed. - // - // Running containers must first be stopped using Signal(..). - // Paused containers must first be resumed using Resume(..). - Destroy() error - - // Signal sends the provided signal code to the container's initial process. - // - // If all is specified the signal is sent to all processes in the container - // including the initial process. - Signal(s os.Signal, all bool) error - - // Exec signals the container to exec the users process at the end of the init. - Exec() error -} diff --git a/vendor/github.com/opencontainers/runc/libcontainer/container_linux.go b/vendor/github.com/opencontainers/runc/libcontainer/container_linux.go deleted file mode 100644 index 0c07ae6c875..00000000000 --- a/vendor/github.com/opencontainers/runc/libcontainer/container_linux.go +++ /dev/null @@ -1,2267 +0,0 @@ -package libcontainer - -import ( - "bytes" - "encoding/json" - "errors" - "fmt" - "io" - "net" - "os" - "os/exec" - "path" - "path/filepath" - "reflect" - "strconv" - "strings" - "sync" - "time" - - "github.com/checkpoint-restore/go-criu/v5" - criurpc "github.com/checkpoint-restore/go-criu/v5/rpc" - securejoin "github.com/cyphar/filepath-securejoin" - "github.com/opencontainers/runtime-spec/specs-go" - "github.com/sirupsen/logrus" - "github.com/vishvananda/netlink/nl" - "golang.org/x/sys/unix" - "google.golang.org/protobuf/proto" - - "github.com/opencontainers/runc/libcontainer/cgroups" - "github.com/opencontainers/runc/libcontainer/configs" - "github.com/opencontainers/runc/libcontainer/intelrdt" - "github.com/opencontainers/runc/libcontainer/system" - "github.com/opencontainers/runc/libcontainer/utils" -) - -const stdioFdCount = 3 - -type linuxContainer struct { - id string - root string - config *configs.Config - cgroupManager cgroups.Manager - intelRdtManager *intelrdt.Manager - initPath string - initArgs []string - initProcess parentProcess - initProcessStartTime uint64 - criuPath string - newuidmapPath string - newgidmapPath string - m sync.Mutex - criuVersion int - state containerState - created time.Time - fifo *os.File -} - -// State represents a running container's state -type State struct { - BaseState - - // Platform specific fields below here - - // Specified if the container was started under the rootless mode. - // Set to true if BaseState.Config.RootlessEUID && BaseState.Config.RootlessCgroups - Rootless bool `json:"rootless"` - - // Paths to all the container's cgroups, as returned by (*cgroups.Manager).GetPaths - // - // For cgroup v1, a key is cgroup subsystem name, and the value is the path - // to the cgroup for this subsystem. - // - // For cgroup v2 unified hierarchy, a key is "", and the value is the unified path. - CgroupPaths map[string]string `json:"cgroup_paths"` - - // NamespacePaths are filepaths to the container's namespaces. Key is the namespace type - // with the value as the path. - NamespacePaths map[configs.NamespaceType]string `json:"namespace_paths"` - - // Container's standard descriptors (std{in,out,err}), needed for checkpoint and restore - ExternalDescriptors []string `json:"external_descriptors,omitempty"` - - // Intel RDT "resource control" filesystem path - IntelRdtPath string `json:"intel_rdt_path"` -} - -// Container is a libcontainer container object. -// -// Each container is thread-safe within the same process. Since a container can -// be destroyed by a separate process, any function may return that the container -// was not found. -type Container interface { - BaseContainer - - // Methods below here are platform specific - - // Checkpoint checkpoints the running container's state to disk using the criu(8) utility. - Checkpoint(criuOpts *CriuOpts) error - - // Restore restores the checkpointed container to a running state using the criu(8) utility. - Restore(process *Process, criuOpts *CriuOpts) error - - // If the Container state is RUNNING or CREATED, sets the Container state to PAUSING and pauses - // the execution of any user processes. Asynchronously, when the container finished being paused the - // state is changed to PAUSED. - // If the Container state is PAUSED, do nothing. - Pause() error - - // If the Container state is PAUSED, resumes the execution of any user processes in the - // Container before setting the Container state to RUNNING. - // If the Container state is RUNNING, do nothing. - Resume() error - - // NotifyOOM returns a read-only channel signaling when the container receives an OOM notification. - NotifyOOM() (<-chan struct{}, error) - - // NotifyMemoryPressure returns a read-only channel signaling when the container reaches a given pressure level - NotifyMemoryPressure(level PressureLevel) (<-chan struct{}, error) -} - -// ID returns the container's unique ID -func (c *linuxContainer) ID() string { - return c.id -} - -// Config returns the container's configuration -func (c *linuxContainer) Config() configs.Config { - return *c.config -} - -func (c *linuxContainer) Status() (Status, error) { - c.m.Lock() - defer c.m.Unlock() - return c.currentStatus() -} - -func (c *linuxContainer) State() (*State, error) { - c.m.Lock() - defer c.m.Unlock() - return c.currentState() -} - -func (c *linuxContainer) OCIState() (*specs.State, error) { - c.m.Lock() - defer c.m.Unlock() - return c.currentOCIState() -} - -// ignoreCgroupError filters out cgroup-related errors that can be ignored, -// because the container is stopped and its cgroup is gone. -func (c *linuxContainer) ignoreCgroupError(err error) error { - if err == nil { - return nil - } - if errors.Is(err, os.ErrNotExist) && c.runType() == Stopped && !c.cgroupManager.Exists() { - return nil - } - return err -} - -func (c *linuxContainer) Processes() ([]int, error) { - pids, err := c.cgroupManager.GetAllPids() - if err = c.ignoreCgroupError(err); err != nil { - return nil, fmt.Errorf("unable to get all container pids: %w", err) - } - return pids, nil -} - -func (c *linuxContainer) Stats() (*Stats, error) { - var ( - err error - stats = &Stats{} - ) - if stats.CgroupStats, err = c.cgroupManager.GetStats(); err != nil { - return stats, fmt.Errorf("unable to get container cgroup stats: %w", err) - } - if c.intelRdtManager != nil { - if stats.IntelRdtStats, err = c.intelRdtManager.GetStats(); err != nil { - return stats, fmt.Errorf("unable to get container Intel RDT stats: %w", err) - } - } - for _, iface := range c.config.Networks { - switch iface.Type { - case "veth": - istats, err := getNetworkInterfaceStats(iface.HostInterfaceName) - if err != nil { - return stats, fmt.Errorf("unable to get network stats for interface %q: %w", iface.HostInterfaceName, err) - } - stats.Interfaces = append(stats.Interfaces, istats) - } - } - return stats, nil -} - -func (c *linuxContainer) Set(config configs.Config) error { - c.m.Lock() - defer c.m.Unlock() - status, err := c.currentStatus() - if err != nil { - return err - } - if status == Stopped { - return ErrNotRunning - } - if err := c.cgroupManager.Set(config.Cgroups.Resources); err != nil { - // Set configs back - if err2 := c.cgroupManager.Set(c.config.Cgroups.Resources); err2 != nil { - logrus.Warnf("Setting back cgroup configs failed due to error: %v, your state.json and actual configs might be inconsistent.", err2) - } - return err - } - if c.intelRdtManager != nil { - if err := c.intelRdtManager.Set(&config); err != nil { - // Set configs back - if err2 := c.cgroupManager.Set(c.config.Cgroups.Resources); err2 != nil { - logrus.Warnf("Setting back cgroup configs failed due to error: %v, your state.json and actual configs might be inconsistent.", err2) - } - if err2 := c.intelRdtManager.Set(c.config); err2 != nil { - logrus.Warnf("Setting back intelrdt configs failed due to error: %v, your state.json and actual configs might be inconsistent.", err2) - } - return err - } - } - // After config setting succeed, update config and states - c.config = &config - _, err = c.updateState(nil) - return err -} - -func (c *linuxContainer) Start(process *Process) error { - c.m.Lock() - defer c.m.Unlock() - if c.config.Cgroups.Resources.SkipDevices { - return errors.New("can't start container with SkipDevices set") - } - if process.Init { - if err := c.createExecFifo(); err != nil { - return err - } - } - if err := c.start(process); err != nil { - if process.Init { - c.deleteExecFifo() - } - return err - } - return nil -} - -func (c *linuxContainer) Run(process *Process) error { - if err := c.Start(process); err != nil { - return err - } - if process.Init { - return c.exec() - } - return nil -} - -func (c *linuxContainer) Exec() error { - c.m.Lock() - defer c.m.Unlock() - return c.exec() -} - -func (c *linuxContainer) exec() error { - path := filepath.Join(c.root, execFifoFilename) - pid := c.initProcess.pid() - blockingFifoOpenCh := awaitFifoOpen(path) - for { - select { - case result := <-blockingFifoOpenCh: - return handleFifoResult(result) - - case <-time.After(time.Millisecond * 100): - stat, err := system.Stat(pid) - if err != nil || stat.State == system.Zombie { - // could be because process started, ran, and completed between our 100ms timeout and our system.Stat() check. - // see if the fifo exists and has data (with a non-blocking open, which will succeed if the writing process is complete). - if err := handleFifoResult(fifoOpen(path, false)); err != nil { - return errors.New("container process is already dead") - } - return nil - } - } - } -} - -func readFromExecFifo(execFifo io.Reader) error { - data, err := io.ReadAll(execFifo) - if err != nil { - return err - } - if len(data) <= 0 { - return errors.New("cannot start an already running container") - } - return nil -} - -func awaitFifoOpen(path string) <-chan openResult { - fifoOpened := make(chan openResult) - go func() { - result := fifoOpen(path, true) - fifoOpened <- result - }() - return fifoOpened -} - -func fifoOpen(path string, block bool) openResult { - flags := os.O_RDONLY - if !block { - flags |= unix.O_NONBLOCK - } - f, err := os.OpenFile(path, flags, 0) - if err != nil { - return openResult{err: fmt.Errorf("exec fifo: %w", err)} - } - return openResult{file: f} -} - -func handleFifoResult(result openResult) error { - if result.err != nil { - return result.err - } - f := result.file - defer f.Close() - if err := readFromExecFifo(f); err != nil { - return err - } - return os.Remove(f.Name()) -} - -type openResult struct { - file *os.File - err error -} - -func (c *linuxContainer) start(process *Process) (retErr error) { - parent, err := c.newParentProcess(process) - if err != nil { - return fmt.Errorf("unable to create new parent process: %w", err) - } - - logsDone := parent.forwardChildLogs() - if logsDone != nil { - defer func() { - // Wait for log forwarder to finish. This depends on - // runc init closing the _LIBCONTAINER_LOGPIPE log fd. - err := <-logsDone - if err != nil && retErr == nil { - retErr = fmt.Errorf("unable to forward init logs: %w", err) - } - }() - } - - // Before starting "runc init", mark all non-stdio open files as O_CLOEXEC - // to make sure we don't leak any files into "runc init". Any files to be - // passed to "runc init" through ExtraFiles will get dup2'd by the Go - // runtime and thus their O_CLOEXEC flag will be cleared. This is some - // additional protection against attacks like CVE-2024-21626, by making - // sure we never leak files to "runc init" we didn't intend to. - if err := utils.CloseExecFrom(3); err != nil { - return fmt.Errorf("unable to mark non-stdio fds as cloexec: %w", err) - } - if err := parent.start(); err != nil { - return fmt.Errorf("unable to start container process: %w", err) - } - - if process.Init { - c.fifo.Close() - if c.config.Hooks != nil { - s, err := c.currentOCIState() - if err != nil { - return err - } - - if err := c.config.Hooks[configs.Poststart].RunHooks(s); err != nil { - if err := ignoreTerminateErrors(parent.terminate()); err != nil { - logrus.Warn(fmt.Errorf("error running poststart hook: %w", err)) - } - return err - } - } - } - return nil -} - -func (c *linuxContainer) Signal(s os.Signal, all bool) error { - c.m.Lock() - defer c.m.Unlock() - status, err := c.currentStatus() - if err != nil { - return err - } - if all { - if status == Stopped && !c.cgroupManager.Exists() { - // Avoid calling signalAllProcesses which may print - // a warning trying to freeze a non-existing cgroup. - return nil - } - return c.ignoreCgroupError(signalAllProcesses(c.cgroupManager, s)) - } - // to avoid a PID reuse attack - if status == Running || status == Created || status == Paused { - if err := c.initProcess.signal(s); err != nil { - return fmt.Errorf("unable to signal init: %w", err) - } - if status == Paused { - // For cgroup v1, killing a process in a frozen cgroup - // does nothing until it's thawed. Only thaw the cgroup - // for SIGKILL. - if s, ok := s.(unix.Signal); ok && s == unix.SIGKILL { - _ = c.cgroupManager.Freeze(configs.Thawed) - } - } - return nil - } - return ErrNotRunning -} - -func (c *linuxContainer) createExecFifo() error { - rootuid, err := c.Config().HostRootUID() - if err != nil { - return err - } - rootgid, err := c.Config().HostRootGID() - if err != nil { - return err - } - - fifoName := filepath.Join(c.root, execFifoFilename) - if _, err := os.Stat(fifoName); err == nil { - return fmt.Errorf("exec fifo %s already exists", fifoName) - } - oldMask := unix.Umask(0o000) - if err := unix.Mkfifo(fifoName, 0o622); err != nil { - unix.Umask(oldMask) - return err - } - unix.Umask(oldMask) - return os.Chown(fifoName, rootuid, rootgid) -} - -func (c *linuxContainer) deleteExecFifo() { - fifoName := filepath.Join(c.root, execFifoFilename) - os.Remove(fifoName) -} - -// includeExecFifo opens the container's execfifo as a pathfd, so that the -// container cannot access the statedir (and the FIFO itself remains -// un-opened). It then adds the FifoFd to the given exec.Cmd as an inherited -// fd, with _LIBCONTAINER_FIFOFD set to its fd number. -func (c *linuxContainer) includeExecFifo(cmd *exec.Cmd) error { - fifoName := filepath.Join(c.root, execFifoFilename) - fifo, err := os.OpenFile(fifoName, unix.O_PATH|unix.O_CLOEXEC, 0) - if err != nil { - return err - } - c.fifo = fifo - - cmd.ExtraFiles = append(cmd.ExtraFiles, fifo) - cmd.Env = append(cmd.Env, - "_LIBCONTAINER_FIFOFD="+strconv.Itoa(stdioFdCount+len(cmd.ExtraFiles)-1)) - return nil -} - -func (c *linuxContainer) newParentProcess(p *Process) (parentProcess, error) { - parentInitPipe, childInitPipe, err := utils.NewSockPair("init") - if err != nil { - return nil, fmt.Errorf("unable to create init pipe: %w", err) - } - messageSockPair := filePair{parentInitPipe, childInitPipe} - - parentLogPipe, childLogPipe, err := os.Pipe() - if err != nil { - return nil, fmt.Errorf("unable to create log pipe: %w", err) - } - logFilePair := filePair{parentLogPipe, childLogPipe} - - cmd := c.commandTemplate(p, childInitPipe, childLogPipe) - if !p.Init { - return c.newSetnsProcess(p, cmd, messageSockPair, logFilePair) - } - - // We only set up fifoFd if we're not doing a `runc exec`. The historic - // reason for this is that previously we would pass a dirfd that allowed - // for container rootfs escape (and not doing it in `runc exec` avoided - // that problem), but we no longer do that. However, there's no need to do - // this for `runc exec` so we just keep it this way to be safe. - if err := c.includeExecFifo(cmd); err != nil { - return nil, fmt.Errorf("unable to setup exec fifo: %w", err) - } - return c.newInitProcess(p, cmd, messageSockPair, logFilePair) -} - -func (c *linuxContainer) commandTemplate(p *Process, childInitPipe *os.File, childLogPipe *os.File) *exec.Cmd { - cmd := exec.Command(c.initPath, c.initArgs[1:]...) - cmd.Args[0] = c.initArgs[0] - cmd.Stdin = p.Stdin - cmd.Stdout = p.Stdout - cmd.Stderr = p.Stderr - cmd.Dir = c.config.Rootfs - if cmd.SysProcAttr == nil { - cmd.SysProcAttr = &unix.SysProcAttr{} - } - cmd.Env = append(cmd.Env, "GOMAXPROCS="+os.Getenv("GOMAXPROCS")) - cmd.ExtraFiles = append(cmd.ExtraFiles, p.ExtraFiles...) - if p.ConsoleSocket != nil { - cmd.ExtraFiles = append(cmd.ExtraFiles, p.ConsoleSocket) - cmd.Env = append(cmd.Env, - "_LIBCONTAINER_CONSOLE="+strconv.Itoa(stdioFdCount+len(cmd.ExtraFiles)-1), - ) - } - cmd.ExtraFiles = append(cmd.ExtraFiles, childInitPipe) - cmd.Env = append(cmd.Env, - "_LIBCONTAINER_INITPIPE="+strconv.Itoa(stdioFdCount+len(cmd.ExtraFiles)-1), - "_LIBCONTAINER_STATEDIR="+c.root, - ) - - cmd.ExtraFiles = append(cmd.ExtraFiles, childLogPipe) - cmd.Env = append(cmd.Env, - "_LIBCONTAINER_LOGPIPE="+strconv.Itoa(stdioFdCount+len(cmd.ExtraFiles)-1), - "_LIBCONTAINER_LOGLEVEL="+p.LogLevel, - ) - - // NOTE: when running a container with no PID namespace and the parent process spawning the container is - // PID1 the pdeathsig is being delivered to the container's init process by the kernel for some reason - // even with the parent still running. - if c.config.ParentDeathSignal > 0 { - cmd.SysProcAttr.Pdeathsig = unix.Signal(c.config.ParentDeathSignal) - } - return cmd -} - -// shouldSendMountSources says whether the child process must setup bind mounts with -// the source pre-opened (O_PATH) in the host user namespace. -// See https://github.com/opencontainers/runc/issues/2484 -func (c *linuxContainer) shouldSendMountSources() bool { - // Passing the mount sources via SCM_RIGHTS is only necessary when - // both userns and mntns are active. - if !c.config.Namespaces.Contains(configs.NEWUSER) || - !c.config.Namespaces.Contains(configs.NEWNS) { - return false - } - - // nsexec.c send_mountsources() requires setns(mntns) capabilities - // CAP_SYS_CHROOT and CAP_SYS_ADMIN. - if c.config.RootlessEUID { - return false - } - - // We need to send sources if there are bind-mounts. - for _, m := range c.config.Mounts { - if m.IsBind() { - return true - } - } - - return false -} - -func (c *linuxContainer) newInitProcess(p *Process, cmd *exec.Cmd, messageSockPair, logFilePair filePair) (*initProcess, error) { - cmd.Env = append(cmd.Env, "_LIBCONTAINER_INITTYPE="+string(initStandard)) - nsMaps := make(map[configs.NamespaceType]string) - for _, ns := range c.config.Namespaces { - if ns.Path != "" { - nsMaps[ns.Type] = ns.Path - } - } - _, sharePidns := nsMaps[configs.NEWPID] - data, err := c.bootstrapData(c.config.Namespaces.CloneFlags(), nsMaps, initStandard) - if err != nil { - return nil, err - } - - if c.shouldSendMountSources() { - // Elements on this slice will be paired with mounts (see StartInitialization() and - // prepareRootfs()). This slice MUST have the same size as c.config.Mounts. - mountFds := make([]int, len(c.config.Mounts)) - for i, m := range c.config.Mounts { - if !m.IsBind() { - // Non bind-mounts do not use an fd. - mountFds[i] = -1 - continue - } - - // The fd passed here will not be used: nsexec.c will overwrite it with dup3(). We just need - // to allocate a fd so that we know the number to pass in the environment variable. The fd - // must not be closed before cmd.Start(), so we reuse messageSockPair.child because the - // lifecycle of that fd is already taken care of. - cmd.ExtraFiles = append(cmd.ExtraFiles, messageSockPair.child) - mountFds[i] = stdioFdCount + len(cmd.ExtraFiles) - 1 - } - - mountFdsJson, err := json.Marshal(mountFds) - if err != nil { - return nil, fmt.Errorf("Error creating _LIBCONTAINER_MOUNT_FDS: %w", err) - } - - cmd.Env = append(cmd.Env, - "_LIBCONTAINER_MOUNT_FDS="+string(mountFdsJson), - ) - } - - init := &initProcess{ - cmd: cmd, - messageSockPair: messageSockPair, - logFilePair: logFilePair, - manager: c.cgroupManager, - intelRdtManager: c.intelRdtManager, - config: c.newInitConfig(p), - container: c, - process: p, - bootstrapData: data, - sharePidns: sharePidns, - } - c.initProcess = init - return init, nil -} - -func (c *linuxContainer) newSetnsProcess(p *Process, cmd *exec.Cmd, messageSockPair, logFilePair filePair) (*setnsProcess, error) { - cmd.Env = append(cmd.Env, "_LIBCONTAINER_INITTYPE="+string(initSetns)) - state, err := c.currentState() - if err != nil { - return nil, fmt.Errorf("unable to get container state: %w", err) - } - // for setns process, we don't have to set cloneflags as the process namespaces - // will only be set via setns syscall - data, err := c.bootstrapData(0, state.NamespacePaths, initSetns) - if err != nil { - return nil, err - } - proc := &setnsProcess{ - cmd: cmd, - cgroupPaths: state.CgroupPaths, - rootlessCgroups: c.config.RootlessCgroups, - intelRdtPath: state.IntelRdtPath, - messageSockPair: messageSockPair, - logFilePair: logFilePair, - manager: c.cgroupManager, - config: c.newInitConfig(p), - process: p, - bootstrapData: data, - initProcessPid: state.InitProcessPid, - } - if len(p.SubCgroupPaths) > 0 { - if add, ok := p.SubCgroupPaths[""]; ok { - // cgroup v1: using the same path for all controllers. - // cgroup v2: the only possible way. - for k := range proc.cgroupPaths { - subPath := path.Join(proc.cgroupPaths[k], add) - if !strings.HasPrefix(subPath, proc.cgroupPaths[k]) { - return nil, fmt.Errorf("%s is not a sub cgroup path", add) - } - proc.cgroupPaths[k] = subPath - } - // cgroup v2: do not try to join init process's cgroup - // as a fallback (see (*setnsProcess).start). - proc.initProcessPid = 0 - } else { - // Per-controller paths. - for ctrl, add := range p.SubCgroupPaths { - if val, ok := proc.cgroupPaths[ctrl]; ok { - subPath := path.Join(val, add) - if !strings.HasPrefix(subPath, val) { - return nil, fmt.Errorf("%s is not a sub cgroup path", add) - } - proc.cgroupPaths[ctrl] = subPath - } else { - return nil, fmt.Errorf("unknown controller %s in SubCgroupPaths", ctrl) - } - } - } - } - return proc, nil -} - -func (c *linuxContainer) newInitConfig(process *Process) *initConfig { - cfg := &initConfig{ - Config: c.config, - Args: process.Args, - Env: process.Env, - User: process.User, - AdditionalGroups: process.AdditionalGroups, - Cwd: process.Cwd, - Capabilities: process.Capabilities, - PassedFilesCount: len(process.ExtraFiles), - ContainerId: c.ID(), - NoNewPrivileges: c.config.NoNewPrivileges, - RootlessEUID: c.config.RootlessEUID, - RootlessCgroups: c.config.RootlessCgroups, - AppArmorProfile: c.config.AppArmorProfile, - ProcessLabel: c.config.ProcessLabel, - Rlimits: c.config.Rlimits, - CreateConsole: process.ConsoleSocket != nil, - ConsoleWidth: process.ConsoleWidth, - ConsoleHeight: process.ConsoleHeight, - } - if process.NoNewPrivileges != nil { - cfg.NoNewPrivileges = *process.NoNewPrivileges - } - if process.AppArmorProfile != "" { - cfg.AppArmorProfile = process.AppArmorProfile - } - if process.Label != "" { - cfg.ProcessLabel = process.Label - } - if len(process.Rlimits) > 0 { - cfg.Rlimits = process.Rlimits - } - if cgroups.IsCgroup2UnifiedMode() { - cfg.Cgroup2Path = c.cgroupManager.Path("") - } - - return cfg -} - -func (c *linuxContainer) Destroy() error { - c.m.Lock() - defer c.m.Unlock() - return c.state.destroy() -} - -func (c *linuxContainer) Pause() error { - c.m.Lock() - defer c.m.Unlock() - status, err := c.currentStatus() - if err != nil { - return err - } - switch status { - case Running, Created: - if err := c.cgroupManager.Freeze(configs.Frozen); err != nil { - return err - } - return c.state.transition(&pausedState{ - c: c, - }) - } - return ErrNotRunning -} - -func (c *linuxContainer) Resume() error { - c.m.Lock() - defer c.m.Unlock() - status, err := c.currentStatus() - if err != nil { - return err - } - if status != Paused { - return ErrNotPaused - } - if err := c.cgroupManager.Freeze(configs.Thawed); err != nil { - return err - } - return c.state.transition(&runningState{ - c: c, - }) -} - -func (c *linuxContainer) NotifyOOM() (<-chan struct{}, error) { - // XXX(cyphar): This requires cgroups. - if c.config.RootlessCgroups { - logrus.Warn("getting OOM notifications may fail if you don't have the full access to cgroups") - } - path := c.cgroupManager.Path("memory") - if cgroups.IsCgroup2UnifiedMode() { - return notifyOnOOMV2(path) - } - return notifyOnOOM(path) -} - -func (c *linuxContainer) NotifyMemoryPressure(level PressureLevel) (<-chan struct{}, error) { - // XXX(cyphar): This requires cgroups. - if c.config.RootlessCgroups { - logrus.Warn("getting memory pressure notifications may fail if you don't have the full access to cgroups") - } - return notifyMemoryPressure(c.cgroupManager.Path("memory"), level) -} - -var criuFeatures *criurpc.CriuFeatures - -func (c *linuxContainer) checkCriuFeatures(criuOpts *CriuOpts, rpcOpts *criurpc.CriuOpts, criuFeat *criurpc.CriuFeatures) error { - t := criurpc.CriuReqType_FEATURE_CHECK - - // make sure the features we are looking for are really not from - // some previous check - criuFeatures = nil - - req := &criurpc.CriuReq{ - Type: &t, - // Theoretically this should not be necessary but CRIU - // segfaults if Opts is empty. - // Fixed in CRIU 2.12 - Opts: rpcOpts, - Features: criuFeat, - } - - err := c.criuSwrk(nil, req, criuOpts, nil) - if err != nil { - logrus.Debugf("%s", err) - return errors.New("CRIU feature check failed") - } - - missingFeatures := false - - // The outer if checks if the fields actually exist - if (criuFeat.MemTrack != nil) && - (criuFeatures.MemTrack != nil) { - // The inner if checks if they are set to true - if *criuFeat.MemTrack && !*criuFeatures.MemTrack { - missingFeatures = true - logrus.Debugf("CRIU does not support MemTrack") - } - } - - // This needs to be repeated for every new feature check. - // Is there a way to put this in a function. Reflection? - if (criuFeat.LazyPages != nil) && - (criuFeatures.LazyPages != nil) { - if *criuFeat.LazyPages && !*criuFeatures.LazyPages { - missingFeatures = true - logrus.Debugf("CRIU does not support LazyPages") - } - } - - if missingFeatures { - return errors.New("CRIU is missing features") - } - - return nil -} - -func compareCriuVersion(criuVersion int, minVersion int) error { - // simple function to perform the actual version compare - if criuVersion < minVersion { - return fmt.Errorf("CRIU version %d must be %d or higher", criuVersion, minVersion) - } - - return nil -} - -// checkCriuVersion checks Criu version greater than or equal to minVersion -func (c *linuxContainer) checkCriuVersion(minVersion int) error { - // If the version of criu has already been determined there is no need - // to ask criu for the version again. Use the value from c.criuVersion. - if c.criuVersion != 0 { - return compareCriuVersion(c.criuVersion, minVersion) - } - - criu := criu.MakeCriu() - criu.SetCriuPath(c.criuPath) - var err error - c.criuVersion, err = criu.GetCriuVersion() - if err != nil { - return fmt.Errorf("CRIU version check failed: %w", err) - } - - return compareCriuVersion(c.criuVersion, minVersion) -} - -const descriptorsFilename = "descriptors.json" - -func (c *linuxContainer) addCriuDumpMount(req *criurpc.CriuReq, m *configs.Mount) { - mountDest := strings.TrimPrefix(m.Destination, c.config.Rootfs) - if dest, err := securejoin.SecureJoin(c.config.Rootfs, mountDest); err == nil { - mountDest = dest[len(c.config.Rootfs):] - } - extMnt := &criurpc.ExtMountMap{ - Key: proto.String(mountDest), - Val: proto.String(mountDest), - } - req.Opts.ExtMnt = append(req.Opts.ExtMnt, extMnt) -} - -func (c *linuxContainer) addMaskPaths(req *criurpc.CriuReq) error { - for _, path := range c.config.MaskPaths { - fi, err := os.Stat(fmt.Sprintf("/proc/%d/root/%s", c.initProcess.pid(), path)) - if err != nil { - if os.IsNotExist(err) { - continue - } - return err - } - if fi.IsDir() { - continue - } - - extMnt := &criurpc.ExtMountMap{ - Key: proto.String(path), - Val: proto.String("/dev/null"), - } - req.Opts.ExtMnt = append(req.Opts.ExtMnt, extMnt) - } - return nil -} - -func (c *linuxContainer) handleCriuConfigurationFile(rpcOpts *criurpc.CriuOpts) { - // CRIU will evaluate a configuration starting with release 3.11. - // Settings in the configuration file will overwrite RPC settings. - // Look for annotations. The annotation 'org.criu.config' - // specifies if CRIU should use a different, container specific - // configuration file. - _, annotations := utils.Annotations(c.config.Labels) - configFile, exists := annotations["org.criu.config"] - if exists { - // If the annotation 'org.criu.config' exists and is set - // to a non-empty string, tell CRIU to use that as a - // configuration file. If the file does not exist, CRIU - // will just ignore it. - if configFile != "" { - rpcOpts.ConfigFile = proto.String(configFile) - } - // If 'org.criu.config' exists and is set to an empty - // string, a runc specific CRIU configuration file will - // be not set at all. - } else { - // If the mentioned annotation has not been found, specify - // a default CRIU configuration file. - rpcOpts.ConfigFile = proto.String("/etc/criu/runc.conf") - } -} - -func (c *linuxContainer) criuSupportsExtNS(t configs.NamespaceType) bool { - var minVersion int - switch t { - case configs.NEWNET: - // CRIU supports different external namespace with different released CRIU versions. - // For network namespaces to work we need at least criu 3.11.0 => 31100. - minVersion = 31100 - case configs.NEWPID: - // For PID namespaces criu 31500 is needed. - minVersion = 31500 - default: - return false - } - return c.checkCriuVersion(minVersion) == nil -} - -func criuNsToKey(t configs.NamespaceType) string { - return "extRoot" + strings.Title(configs.NsName(t)) + "NS" //nolint:staticcheck // SA1019: strings.Title is deprecated -} - -func (c *linuxContainer) handleCheckpointingExternalNamespaces(rpcOpts *criurpc.CriuOpts, t configs.NamespaceType) error { - if !c.criuSupportsExtNS(t) { - return nil - } - - nsPath := c.config.Namespaces.PathOf(t) - if nsPath == "" { - return nil - } - // CRIU expects the information about an external namespace - // like this: --external []: - // This is always 'extRootNS'. - var ns unix.Stat_t - if err := unix.Stat(nsPath, &ns); err != nil { - return err - } - criuExternal := fmt.Sprintf("%s[%d]:%s", configs.NsName(t), ns.Ino, criuNsToKey(t)) - rpcOpts.External = append(rpcOpts.External, criuExternal) - - return nil -} - -func (c *linuxContainer) handleRestoringNamespaces(rpcOpts *criurpc.CriuOpts, extraFiles *[]*os.File) error { - for _, ns := range c.config.Namespaces { - switch ns.Type { - case configs.NEWNET, configs.NEWPID: - // If the container is running in a network or PID namespace and has - // a path to the network or PID namespace configured, we will dump - // that network or PID namespace as an external namespace and we - // will expect that the namespace exists during restore. - // This basically means that CRIU will ignore the namespace - // and expect it to be setup correctly. - if err := c.handleRestoringExternalNamespaces(rpcOpts, extraFiles, ns.Type); err != nil { - return err - } - default: - // For all other namespaces except NET and PID CRIU has - // a simpler way of joining the existing namespace if set - nsPath := c.config.Namespaces.PathOf(ns.Type) - if nsPath == "" { - continue - } - if ns.Type == configs.NEWCGROUP { - // CRIU has no code to handle NEWCGROUP - return fmt.Errorf("Do not know how to handle namespace %v", ns.Type) - } - // CRIU has code to handle NEWTIME, but it does not seem to be defined in runc - - // CRIU will issue a warning for NEWUSER: - // criu/namespaces.c: 'join-ns with user-namespace is not fully tested and dangerous' - rpcOpts.JoinNs = append(rpcOpts.JoinNs, &criurpc.JoinNamespace{ - Ns: proto.String(configs.NsName(ns.Type)), - NsFile: proto.String(nsPath), - }) - } - } - - return nil -} - -func (c *linuxContainer) handleRestoringExternalNamespaces(rpcOpts *criurpc.CriuOpts, extraFiles *[]*os.File, t configs.NamespaceType) error { - if !c.criuSupportsExtNS(t) { - return nil - } - - nsPath := c.config.Namespaces.PathOf(t) - if nsPath == "" { - return nil - } - // CRIU wants the information about an existing namespace - // like this: --inherit-fd fd[]: - // The needs to be the same as during checkpointing. - // We are always using 'extRootNS' as the key in this. - nsFd, err := os.Open(nsPath) - if err != nil { - logrus.Errorf("If a specific network namespace is defined it must exist: %s", err) - return fmt.Errorf("Requested network namespace %v does not exist", nsPath) - } - inheritFd := &criurpc.InheritFd{ - Key: proto.String(criuNsToKey(t)), - // The offset of four is necessary because 0, 1, 2 and 3 are - // already used by stdin, stdout, stderr, 'criu swrk' socket. - Fd: proto.Int32(int32(4 + len(*extraFiles))), - } - rpcOpts.InheritFd = append(rpcOpts.InheritFd, inheritFd) - // All open FDs need to be transferred to CRIU via extraFiles - *extraFiles = append(*extraFiles, nsFd) - - return nil -} - -func (c *linuxContainer) Checkpoint(criuOpts *CriuOpts) error { - c.m.Lock() - defer c.m.Unlock() - - // Checkpoint is unlikely to work if os.Geteuid() != 0 || system.RunningInUserNS(). - // (CLI prints a warning) - // TODO(avagin): Figure out how to make this work nicely. CRIU 2.0 has - // support for doing unprivileged dumps, but the setup of - // rootless containers might make this complicated. - - // We are relying on the CRIU version RPC which was introduced with CRIU 3.0.0 - if err := c.checkCriuVersion(30000); err != nil { - return err - } - - if criuOpts.ImagesDirectory == "" { - return errors.New("invalid directory to save checkpoint") - } - - // Since a container can be C/R'ed multiple times, - // the checkpoint directory may already exist. - if err := os.Mkdir(criuOpts.ImagesDirectory, 0o700); err != nil && !os.IsExist(err) { - return err - } - - imageDir, err := os.Open(criuOpts.ImagesDirectory) - if err != nil { - return err - } - defer imageDir.Close() - - rpcOpts := criurpc.CriuOpts{ - ImagesDirFd: proto.Int32(int32(imageDir.Fd())), - LogLevel: proto.Int32(4), - LogFile: proto.String("dump.log"), - Root: proto.String(c.config.Rootfs), - ManageCgroups: proto.Bool(true), - NotifyScripts: proto.Bool(true), - Pid: proto.Int32(int32(c.initProcess.pid())), - ShellJob: proto.Bool(criuOpts.ShellJob), - LeaveRunning: proto.Bool(criuOpts.LeaveRunning), - TcpEstablished: proto.Bool(criuOpts.TcpEstablished), - ExtUnixSk: proto.Bool(criuOpts.ExternalUnixConnections), - FileLocks: proto.Bool(criuOpts.FileLocks), - EmptyNs: proto.Uint32(criuOpts.EmptyNs), - OrphanPtsMaster: proto.Bool(true), - AutoDedup: proto.Bool(criuOpts.AutoDedup), - LazyPages: proto.Bool(criuOpts.LazyPages), - } - - // if criuOpts.WorkDirectory is not set, criu default is used. - if criuOpts.WorkDirectory != "" { - if err := os.Mkdir(criuOpts.WorkDirectory, 0o700); err != nil && !os.IsExist(err) { - return err - } - workDir, err := os.Open(criuOpts.WorkDirectory) - if err != nil { - return err - } - defer workDir.Close() - rpcOpts.WorkDirFd = proto.Int32(int32(workDir.Fd())) - } - - c.handleCriuConfigurationFile(&rpcOpts) - - // If the container is running in a network namespace and has - // a path to the network namespace configured, we will dump - // that network namespace as an external namespace and we - // will expect that the namespace exists during restore. - // This basically means that CRIU will ignore the namespace - // and expect to be setup correctly. - if err := c.handleCheckpointingExternalNamespaces(&rpcOpts, configs.NEWNET); err != nil { - return err - } - - // Same for possible external PID namespaces - if err := c.handleCheckpointingExternalNamespaces(&rpcOpts, configs.NEWPID); err != nil { - return err - } - - // CRIU can use cgroup freezer; when rpcOpts.FreezeCgroup - // is not set, CRIU uses ptrace() to pause the processes. - // Note cgroup v2 freezer is only supported since CRIU release 3.14. - if !cgroups.IsCgroup2UnifiedMode() || c.checkCriuVersion(31400) == nil { - if fcg := c.cgroupManager.Path("freezer"); fcg != "" { - rpcOpts.FreezeCgroup = proto.String(fcg) - } - } - - // append optional criu opts, e.g., page-server and port - if criuOpts.PageServer.Address != "" && criuOpts.PageServer.Port != 0 { - rpcOpts.Ps = &criurpc.CriuPageServerInfo{ - Address: proto.String(criuOpts.PageServer.Address), - Port: proto.Int32(criuOpts.PageServer.Port), - } - } - - // pre-dump may need parentImage param to complete iterative migration - if criuOpts.ParentImage != "" { - rpcOpts.ParentImg = proto.String(criuOpts.ParentImage) - rpcOpts.TrackMem = proto.Bool(true) - } - - // append optional manage cgroups mode - if criuOpts.ManageCgroupsMode != 0 { - mode := criuOpts.ManageCgroupsMode - rpcOpts.ManageCgroupsMode = &mode - } - - var t criurpc.CriuReqType - if criuOpts.PreDump { - feat := criurpc.CriuFeatures{ - MemTrack: proto.Bool(true), - } - - if err := c.checkCriuFeatures(criuOpts, &rpcOpts, &feat); err != nil { - return err - } - - t = criurpc.CriuReqType_PRE_DUMP - } else { - t = criurpc.CriuReqType_DUMP - } - - if criuOpts.LazyPages { - // lazy migration requested; check if criu supports it - feat := criurpc.CriuFeatures{ - LazyPages: proto.Bool(true), - } - if err := c.checkCriuFeatures(criuOpts, &rpcOpts, &feat); err != nil { - return err - } - - if fd := criuOpts.StatusFd; fd != -1 { - // check that the FD is valid - flags, err := unix.FcntlInt(uintptr(fd), unix.F_GETFL, 0) - if err != nil { - return fmt.Errorf("invalid --status-fd argument %d: %w", fd, err) - } - // and writable - if flags&unix.O_WRONLY == 0 { - return fmt.Errorf("invalid --status-fd argument %d: not writable", fd) - } - - if c.checkCriuVersion(31500) != nil { - // For criu 3.15+, use notifications (see case "status-ready" - // in criuNotifications). Otherwise, rely on criu status fd. - rpcOpts.StatusFd = proto.Int32(int32(fd)) - } - } - } - - req := &criurpc.CriuReq{ - Type: &t, - Opts: &rpcOpts, - } - - // no need to dump all this in pre-dump - if !criuOpts.PreDump { - hasCgroupns := c.config.Namespaces.Contains(configs.NEWCGROUP) - for _, m := range c.config.Mounts { - switch m.Device { - case "bind": - c.addCriuDumpMount(req, m) - case "cgroup": - if cgroups.IsCgroup2UnifiedMode() || hasCgroupns { - // real mount(s) - continue - } - // a set of "external" bind mounts - binds, err := getCgroupMounts(m) - if err != nil { - return err - } - for _, b := range binds { - c.addCriuDumpMount(req, b) - } - } - } - - if err := c.addMaskPaths(req); err != nil { - return err - } - - for _, node := range c.config.Devices { - m := &configs.Mount{Destination: node.Path, Source: node.Path} - c.addCriuDumpMount(req, m) - } - - // Write the FD info to a file in the image directory - fdsJSON, err := json.Marshal(c.initProcess.externalDescriptors()) - if err != nil { - return err - } - - err = os.WriteFile(filepath.Join(criuOpts.ImagesDirectory, descriptorsFilename), fdsJSON, 0o600) - if err != nil { - return err - } - } - - err = c.criuSwrk(nil, req, criuOpts, nil) - if err != nil { - return err - } - return nil -} - -func (c *linuxContainer) addCriuRestoreMount(req *criurpc.CriuReq, m *configs.Mount) { - mountDest := strings.TrimPrefix(m.Destination, c.config.Rootfs) - if dest, err := securejoin.SecureJoin(c.config.Rootfs, mountDest); err == nil { - mountDest = dest[len(c.config.Rootfs):] - } - extMnt := &criurpc.ExtMountMap{ - Key: proto.String(mountDest), - Val: proto.String(m.Source), - } - req.Opts.ExtMnt = append(req.Opts.ExtMnt, extMnt) -} - -func (c *linuxContainer) restoreNetwork(req *criurpc.CriuReq, criuOpts *CriuOpts) { - for _, iface := range c.config.Networks { - switch iface.Type { - case "veth": - veth := new(criurpc.CriuVethPair) - veth.IfOut = proto.String(iface.HostInterfaceName) - veth.IfIn = proto.String(iface.Name) - req.Opts.Veths = append(req.Opts.Veths, veth) - case "loopback": - // Do nothing - } - } - for _, i := range criuOpts.VethPairs { - veth := new(criurpc.CriuVethPair) - veth.IfOut = proto.String(i.HostInterfaceName) - veth.IfIn = proto.String(i.ContainerInterfaceName) - req.Opts.Veths = append(req.Opts.Veths, veth) - } -} - -// makeCriuRestoreMountpoints makes the actual mountpoints for the -// restore using CRIU. This function is inspired from the code in -// rootfs_linux.go -func (c *linuxContainer) makeCriuRestoreMountpoints(m *configs.Mount) error { - if m.Device == "cgroup" { - // No mount point(s) need to be created: - // - // * for v1, mount points are saved by CRIU because - // /sys/fs/cgroup is a tmpfs mount - // - // * for v2, /sys/fs/cgroup is a real mount, but - // the mountpoint appears as soon as /sys is mounted - return nil - } - // TODO: pass something else than nil? Not sure if criu is - // impacted by issue #2484 - if _, err := createMountpoint(c.config.Rootfs, m, nil, ""); err != nil { - return fmt.Errorf("create criu restore mount for %s mount: %w", m.Destination, err) - } - return nil -} - -// isPathInPrefixList is a small function for CRIU restore to make sure -// mountpoints, which are on a tmpfs, are not created in the roofs -func isPathInPrefixList(path string, prefix []string) bool { - for _, p := range prefix { - if strings.HasPrefix(path, p+"/") { - return true - } - } - return false -} - -// prepareCriuRestoreMounts tries to set up the rootfs of the -// container to be restored in the same way runc does it for -// initial container creation. Even for a read-only rootfs container -// runc modifies the rootfs to add mountpoints which do not exist. -// This function also creates missing mountpoints as long as they -// are not on top of a tmpfs, as CRIU will restore tmpfs content anyway. -func (c *linuxContainer) prepareCriuRestoreMounts(mounts []*configs.Mount) error { - // First get a list of a all tmpfs mounts - tmpfs := []string{} - for _, m := range mounts { - switch m.Device { - case "tmpfs": - tmpfs = append(tmpfs, m.Destination) - } - } - // Now go through all mounts and create the mountpoints - // if the mountpoints are not on a tmpfs, as CRIU will - // restore the complete tmpfs content from its checkpoint. - umounts := []string{} - defer func() { - for _, u := range umounts { - _ = utils.WithProcfd(c.config.Rootfs, u, func(procfd string) error { - if e := unix.Unmount(procfd, unix.MNT_DETACH); e != nil { - if e != unix.EINVAL { //nolint:errorlint // unix errors are bare - // Ignore EINVAL as it means 'target is not a mount point.' - // It probably has already been unmounted. - logrus.Warnf("Error during cleanup unmounting of %s (%s): %v", procfd, u, e) - } - } - return nil - }) - } - }() - for _, m := range mounts { - if !isPathInPrefixList(m.Destination, tmpfs) { - if err := c.makeCriuRestoreMountpoints(m); err != nil { - return err - } - // If the mount point is a bind mount, we need to mount - // it now so that runc can create the necessary mount - // points for mounts in bind mounts. - // This also happens during initial container creation. - // Without this CRIU restore will fail - // See: https://github.com/opencontainers/runc/issues/2748 - // It is also not necessary to order the mount points - // because during initial container creation mounts are - // set up in the order they are configured. - if m.Device == "bind" { - if err := utils.WithProcfd(c.config.Rootfs, m.Destination, func(procfd string) error { - if err := mount(m.Source, m.Destination, procfd, "", unix.MS_BIND|unix.MS_REC, ""); err != nil { - return err - } - return nil - }); err != nil { - return err - } - umounts = append(umounts, m.Destination) - } - } - } - return nil -} - -func (c *linuxContainer) Restore(process *Process, criuOpts *CriuOpts) error { - c.m.Lock() - defer c.m.Unlock() - - var extraFiles []*os.File - - // Restore is unlikely to work if os.Geteuid() != 0 || system.RunningInUserNS(). - // (CLI prints a warning) - // TODO(avagin): Figure out how to make this work nicely. CRIU doesn't have - // support for unprivileged restore at the moment. - - // We are relying on the CRIU version RPC which was introduced with CRIU 3.0.0 - if err := c.checkCriuVersion(30000); err != nil { - return err - } - if criuOpts.ImagesDirectory == "" { - return errors.New("invalid directory to restore checkpoint") - } - imageDir, err := os.Open(criuOpts.ImagesDirectory) - if err != nil { - return err - } - defer imageDir.Close() - // CRIU has a few requirements for a root directory: - // * it must be a mount point - // * its parent must not be overmounted - // c.config.Rootfs is bind-mounted to a temporary directory - // to satisfy these requirements. - root := filepath.Join(c.root, "criu-root") - if err := os.Mkdir(root, 0o755); err != nil { - return err - } - defer os.Remove(root) - root, err = filepath.EvalSymlinks(root) - if err != nil { - return err - } - err = mount(c.config.Rootfs, root, "", "", unix.MS_BIND|unix.MS_REC, "") - if err != nil { - return err - } - defer unix.Unmount(root, unix.MNT_DETACH) //nolint: errcheck - t := criurpc.CriuReqType_RESTORE - req := &criurpc.CriuReq{ - Type: &t, - Opts: &criurpc.CriuOpts{ - ImagesDirFd: proto.Int32(int32(imageDir.Fd())), - EvasiveDevices: proto.Bool(true), - LogLevel: proto.Int32(4), - LogFile: proto.String("restore.log"), - RstSibling: proto.Bool(true), - Root: proto.String(root), - ManageCgroups: proto.Bool(true), - NotifyScripts: proto.Bool(true), - ShellJob: proto.Bool(criuOpts.ShellJob), - ExtUnixSk: proto.Bool(criuOpts.ExternalUnixConnections), - TcpEstablished: proto.Bool(criuOpts.TcpEstablished), - FileLocks: proto.Bool(criuOpts.FileLocks), - EmptyNs: proto.Uint32(criuOpts.EmptyNs), - OrphanPtsMaster: proto.Bool(true), - AutoDedup: proto.Bool(criuOpts.AutoDedup), - LazyPages: proto.Bool(criuOpts.LazyPages), - }, - } - - if criuOpts.LsmProfile != "" { - // CRIU older than 3.16 has a bug which breaks the possibility - // to set a different LSM profile. - if err := c.checkCriuVersion(31600); err != nil { - return errors.New("--lsm-profile requires at least CRIU 3.16") - } - req.Opts.LsmProfile = proto.String(criuOpts.LsmProfile) - } - if criuOpts.LsmMountContext != "" { - if err := c.checkCriuVersion(31600); err != nil { - return errors.New("--lsm-mount-context requires at least CRIU 3.16") - } - req.Opts.LsmMountContext = proto.String(criuOpts.LsmMountContext) - } - - if criuOpts.WorkDirectory != "" { - // Since a container can be C/R'ed multiple times, - // the work directory may already exist. - if err := os.Mkdir(criuOpts.WorkDirectory, 0o700); err != nil && !os.IsExist(err) { - return err - } - workDir, err := os.Open(criuOpts.WorkDirectory) - if err != nil { - return err - } - defer workDir.Close() - req.Opts.WorkDirFd = proto.Int32(int32(workDir.Fd())) - } - c.handleCriuConfigurationFile(req.Opts) - - if err := c.handleRestoringNamespaces(req.Opts, &extraFiles); err != nil { - return err - } - - // This will modify the rootfs of the container in the same way runc - // modifies the container during initial creation. - if err := c.prepareCriuRestoreMounts(c.config.Mounts); err != nil { - return err - } - - hasCgroupns := c.config.Namespaces.Contains(configs.NEWCGROUP) - for _, m := range c.config.Mounts { - switch m.Device { - case "bind": - c.addCriuRestoreMount(req, m) - case "cgroup": - if cgroups.IsCgroup2UnifiedMode() || hasCgroupns { - continue - } - // cgroup v1 is a set of bind mounts, unless cgroupns is used - binds, err := getCgroupMounts(m) - if err != nil { - return err - } - for _, b := range binds { - c.addCriuRestoreMount(req, b) - } - } - } - - if len(c.config.MaskPaths) > 0 { - m := &configs.Mount{Destination: "/dev/null", Source: "/dev/null"} - c.addCriuRestoreMount(req, m) - } - - for _, node := range c.config.Devices { - m := &configs.Mount{Destination: node.Path, Source: node.Path} - c.addCriuRestoreMount(req, m) - } - - if criuOpts.EmptyNs&unix.CLONE_NEWNET == 0 { - c.restoreNetwork(req, criuOpts) - } - - // append optional manage cgroups mode - if criuOpts.ManageCgroupsMode != 0 { - mode := criuOpts.ManageCgroupsMode - req.Opts.ManageCgroupsMode = &mode - } - - var ( - fds []string - fdJSON []byte - ) - if fdJSON, err = os.ReadFile(filepath.Join(criuOpts.ImagesDirectory, descriptorsFilename)); err != nil { - return err - } - - if err := json.Unmarshal(fdJSON, &fds); err != nil { - return err - } - for i := range fds { - if s := fds[i]; strings.Contains(s, "pipe:") { - inheritFd := new(criurpc.InheritFd) - inheritFd.Key = proto.String(s) - inheritFd.Fd = proto.Int32(int32(i)) - req.Opts.InheritFd = append(req.Opts.InheritFd, inheritFd) - } - } - err = c.criuSwrk(process, req, criuOpts, extraFiles) - - // Now that CRIU is done let's close all opened FDs CRIU needed. - for _, fd := range extraFiles { - fd.Close() - } - - return err -} - -func (c *linuxContainer) criuApplyCgroups(pid int, req *criurpc.CriuReq) error { - // need to apply cgroups only on restore - if req.GetType() != criurpc.CriuReqType_RESTORE { - return nil - } - - // XXX: Do we need to deal with this case? AFAIK criu still requires root. - if err := c.cgroupManager.Apply(pid); err != nil { - return err - } - - if err := c.cgroupManager.Set(c.config.Cgroups.Resources); err != nil { - return err - } - - if cgroups.IsCgroup2UnifiedMode() { - return nil - } - // the stuff below is cgroupv1-specific - - path := fmt.Sprintf("/proc/%d/cgroup", pid) - cgroupsPaths, err := cgroups.ParseCgroupFile(path) - if err != nil { - return err - } - - for c, p := range cgroupsPaths { - cgroupRoot := &criurpc.CgroupRoot{ - Ctrl: proto.String(c), - Path: proto.String(p), - } - req.Opts.CgRoot = append(req.Opts.CgRoot, cgroupRoot) - } - - return nil -} - -func (c *linuxContainer) criuSwrk(process *Process, req *criurpc.CriuReq, opts *CriuOpts, extraFiles []*os.File) error { - fds, err := unix.Socketpair(unix.AF_LOCAL, unix.SOCK_SEQPACKET|unix.SOCK_CLOEXEC, 0) - if err != nil { - return err - } - - var logPath string - if opts != nil { - logPath = filepath.Join(opts.WorkDirectory, req.GetOpts().GetLogFile()) - } else { - // For the VERSION RPC 'opts' is set to 'nil' and therefore - // opts.WorkDirectory does not exist. Set logPath to "". - logPath = "" - } - criuClient := os.NewFile(uintptr(fds[0]), "criu-transport-client") - criuClientFileCon, err := net.FileConn(criuClient) - criuClient.Close() - if err != nil { - return err - } - - criuClientCon := criuClientFileCon.(*net.UnixConn) - defer criuClientCon.Close() - - criuServer := os.NewFile(uintptr(fds[1]), "criu-transport-server") - defer criuServer.Close() - - args := []string{"swrk", "3"} - if c.criuVersion != 0 { - // If the CRIU Version is still '0' then this is probably - // the initial CRIU run to detect the version. Skip it. - logrus.Debugf("Using CRIU %d at: %s", c.criuVersion, c.criuPath) - } - cmd := exec.Command(c.criuPath, args...) - if process != nil { - cmd.Stdin = process.Stdin - cmd.Stdout = process.Stdout - cmd.Stderr = process.Stderr - } - cmd.ExtraFiles = append(cmd.ExtraFiles, criuServer) - if extraFiles != nil { - cmd.ExtraFiles = append(cmd.ExtraFiles, extraFiles...) - } - - if err := cmd.Start(); err != nil { - return err - } - // we close criuServer so that even if CRIU crashes or unexpectedly exits, runc will not hang. - criuServer.Close() - // cmd.Process will be replaced by a restored init. - criuProcess := cmd.Process - - var criuProcessState *os.ProcessState - defer func() { - if criuProcessState == nil { - criuClientCon.Close() - _, err := criuProcess.Wait() - if err != nil { - logrus.Warnf("wait on criuProcess returned %v", err) - } - } - }() - - if err := c.criuApplyCgroups(criuProcess.Pid, req); err != nil { - return err - } - - var extFds []string - if process != nil { - extFds, err = getPipeFds(criuProcess.Pid) - if err != nil { - return err - } - } - - logrus.Debugf("Using CRIU in %s mode", req.GetType().String()) - // In the case of criurpc.CriuReqType_FEATURE_CHECK req.GetOpts() - // should be empty. For older CRIU versions it still will be - // available but empty. criurpc.CriuReqType_VERSION actually - // has no req.GetOpts(). - if logrus.GetLevel() >= logrus.DebugLevel && - !(req.GetType() == criurpc.CriuReqType_FEATURE_CHECK || - req.GetType() == criurpc.CriuReqType_VERSION) { - - val := reflect.ValueOf(req.GetOpts()) - v := reflect.Indirect(val) - for i := 0; i < v.NumField(); i++ { - st := v.Type() - name := st.Field(i).Name - if 'A' <= name[0] && name[0] <= 'Z' { - value := val.MethodByName("Get" + name).Call([]reflect.Value{}) - logrus.Debugf("CRIU option %s with value %v", name, value[0]) - } - } - } - data, err := proto.Marshal(req) - if err != nil { - return err - } - _, err = criuClientCon.Write(data) - if err != nil { - return err - } - - buf := make([]byte, 10*4096) - oob := make([]byte, 4096) - for { - n, oobn, _, _, err := criuClientCon.ReadMsgUnix(buf, oob) - if req.Opts != nil && req.Opts.StatusFd != nil { - // Close status_fd as soon as we got something back from criu, - // assuming it has consumed (reopened) it by this time. - // Otherwise it will might be left open forever and whoever - // is waiting on it will wait forever. - fd := int(*req.Opts.StatusFd) - _ = unix.Close(fd) - req.Opts.StatusFd = nil - } - if err != nil { - return err - } - if n == 0 { - return errors.New("unexpected EOF") - } - if n == len(buf) { - return errors.New("buffer is too small") - } - - resp := new(criurpc.CriuResp) - err = proto.Unmarshal(buf[:n], resp) - if err != nil { - return err - } - if !resp.GetSuccess() { - typeString := req.GetType().String() - return fmt.Errorf("criu failed: type %s errno %d\nlog file: %s", typeString, resp.GetCrErrno(), logPath) - } - - t := resp.GetType() - switch { - case t == criurpc.CriuReqType_FEATURE_CHECK: - logrus.Debugf("Feature check says: %s", resp) - criuFeatures = resp.GetFeatures() - case t == criurpc.CriuReqType_NOTIFY: - if err := c.criuNotifications(resp, process, cmd, opts, extFds, oob[:oobn]); err != nil { - return err - } - t = criurpc.CriuReqType_NOTIFY - req = &criurpc.CriuReq{ - Type: &t, - NotifySuccess: proto.Bool(true), - } - data, err = proto.Marshal(req) - if err != nil { - return err - } - _, err = criuClientCon.Write(data) - if err != nil { - return err - } - continue - case t == criurpc.CriuReqType_RESTORE: - case t == criurpc.CriuReqType_DUMP: - case t == criurpc.CriuReqType_PRE_DUMP: - default: - return fmt.Errorf("unable to parse the response %s", resp.String()) - } - - break - } - - _ = criuClientCon.CloseWrite() - // cmd.Wait() waits cmd.goroutines which are used for proxying file descriptors. - // Here we want to wait only the CRIU process. - criuProcessState, err = criuProcess.Wait() - if err != nil { - return err - } - - // In pre-dump mode CRIU is in a loop and waits for - // the final DUMP command. - // The current runc pre-dump approach, however, is - // start criu in PRE_DUMP once for a single pre-dump - // and not the whole series of pre-dump, pre-dump, ...m, dump - // If we got the message CriuReqType_PRE_DUMP it means - // CRIU was successful and we need to forcefully stop CRIU - if !criuProcessState.Success() && *req.Type != criurpc.CriuReqType_PRE_DUMP { - return fmt.Errorf("criu failed: %s\nlog file: %s", criuProcessState.String(), logPath) - } - return nil -} - -// block any external network activity -func lockNetwork(config *configs.Config) error { - for _, config := range config.Networks { - strategy, err := getStrategy(config.Type) - if err != nil { - return err - } - - if err := strategy.detach(config); err != nil { - return err - } - } - return nil -} - -func unlockNetwork(config *configs.Config) error { - for _, config := range config.Networks { - strategy, err := getStrategy(config.Type) - if err != nil { - return err - } - if err = strategy.attach(config); err != nil { - return err - } - } - return nil -} - -func (c *linuxContainer) criuNotifications(resp *criurpc.CriuResp, process *Process, cmd *exec.Cmd, opts *CriuOpts, fds []string, oob []byte) error { - notify := resp.GetNotify() - if notify == nil { - return fmt.Errorf("invalid response: %s", resp.String()) - } - script := notify.GetScript() - logrus.Debugf("notify: %s\n", script) - switch script { - case "post-dump": - f, err := os.Create(filepath.Join(c.root, "checkpoint")) - if err != nil { - return err - } - f.Close() - case "network-unlock": - if err := unlockNetwork(c.config); err != nil { - return err - } - case "network-lock": - if err := lockNetwork(c.config); err != nil { - return err - } - case "setup-namespaces": - if c.config.Hooks != nil { - s, err := c.currentOCIState() - if err != nil { - return nil - } - s.Pid = int(notify.GetPid()) - - if err := c.config.Hooks[configs.Prestart].RunHooks(s); err != nil { - return err - } - if err := c.config.Hooks[configs.CreateRuntime].RunHooks(s); err != nil { - return err - } - } - case "post-restore": - pid := notify.GetPid() - - p, err := os.FindProcess(int(pid)) - if err != nil { - return err - } - cmd.Process = p - - r, err := newRestoredProcess(cmd, fds) - if err != nil { - return err - } - process.ops = r - if err := c.state.transition(&restoredState{ - imageDir: opts.ImagesDirectory, - c: c, - }); err != nil { - return err - } - // create a timestamp indicating when the restored checkpoint was started - c.created = time.Now().UTC() - if _, err := c.updateState(r); err != nil { - return err - } - if err := os.Remove(filepath.Join(c.root, "checkpoint")); err != nil { - if !os.IsNotExist(err) { - logrus.Error(err) - } - } - case "orphan-pts-master": - scm, err := unix.ParseSocketControlMessage(oob) - if err != nil { - return err - } - fds, err := unix.ParseUnixRights(&scm[0]) - if err != nil { - return err - } - - master := os.NewFile(uintptr(fds[0]), "orphan-pts-master") - defer master.Close() - - // While we can access console.master, using the API is a good idea. - if err := utils.SendFd(process.ConsoleSocket, master.Name(), master.Fd()); err != nil { - return err - } - case "status-ready": - if opts.StatusFd != -1 { - // write \0 to status fd to notify that lazy page server is ready - _, err := unix.Write(opts.StatusFd, []byte{0}) - if err != nil { - logrus.Warnf("can't write \\0 to status fd: %v", err) - } - _ = unix.Close(opts.StatusFd) - opts.StatusFd = -1 - } - } - return nil -} - -func (c *linuxContainer) updateState(process parentProcess) (*State, error) { - if process != nil { - c.initProcess = process - } - state, err := c.currentState() - if err != nil { - return nil, err - } - err = c.saveState(state) - if err != nil { - return nil, err - } - return state, nil -} - -func (c *linuxContainer) saveState(s *State) (retErr error) { - tmpFile, err := os.CreateTemp(c.root, "state-") - if err != nil { - return err - } - - defer func() { - if retErr != nil { - tmpFile.Close() - os.Remove(tmpFile.Name()) - } - }() - - err = utils.WriteJSON(tmpFile, s) - if err != nil { - return err - } - err = tmpFile.Close() - if err != nil { - return err - } - - stateFilePath := filepath.Join(c.root, stateFilename) - return os.Rename(tmpFile.Name(), stateFilePath) -} - -func (c *linuxContainer) currentStatus() (Status, error) { - if err := c.refreshState(); err != nil { - return -1, err - } - return c.state.status(), nil -} - -// refreshState needs to be called to verify that the current state on the -// container is what is true. Because consumers of libcontainer can use it -// out of process we need to verify the container's status based on runtime -// information and not rely on our in process info. -func (c *linuxContainer) refreshState() error { - paused, err := c.isPaused() - if err != nil { - return err - } - if paused { - return c.state.transition(&pausedState{c: c}) - } - t := c.runType() - switch t { - case Created: - return c.state.transition(&createdState{c: c}) - case Running: - return c.state.transition(&runningState{c: c}) - } - return c.state.transition(&stoppedState{c: c}) -} - -func (c *linuxContainer) runType() Status { - if c.initProcess == nil { - return Stopped - } - pid := c.initProcess.pid() - stat, err := system.Stat(pid) - if err != nil { - return Stopped - } - if stat.StartTime != c.initProcessStartTime || stat.State == system.Zombie || stat.State == system.Dead { - return Stopped - } - // We'll create exec fifo and blocking on it after container is created, - // and delete it after start container. - if _, err := os.Stat(filepath.Join(c.root, execFifoFilename)); err == nil { - return Created - } - return Running -} - -func (c *linuxContainer) isPaused() (bool, error) { - state, err := c.cgroupManager.GetFreezerState() - if err != nil { - return false, err - } - return state == configs.Frozen, nil -} - -func (c *linuxContainer) currentState() (*State, error) { - var ( - startTime uint64 - externalDescriptors []string - pid = -1 - ) - if c.initProcess != nil { - pid = c.initProcess.pid() - startTime, _ = c.initProcess.startTime() - externalDescriptors = c.initProcess.externalDescriptors() - } - - intelRdtPath := "" - if c.intelRdtManager != nil { - intelRdtPath = c.intelRdtManager.GetPath() - } - state := &State{ - BaseState: BaseState{ - ID: c.ID(), - Config: *c.config, - InitProcessPid: pid, - InitProcessStartTime: startTime, - Created: c.created, - }, - Rootless: c.config.RootlessEUID && c.config.RootlessCgroups, - CgroupPaths: c.cgroupManager.GetPaths(), - IntelRdtPath: intelRdtPath, - NamespacePaths: make(map[configs.NamespaceType]string), - ExternalDescriptors: externalDescriptors, - } - if pid > 0 { - for _, ns := range c.config.Namespaces { - state.NamespacePaths[ns.Type] = ns.GetPath(pid) - } - for _, nsType := range configs.NamespaceTypes() { - if !configs.IsNamespaceSupported(nsType) { - continue - } - if _, ok := state.NamespacePaths[nsType]; !ok { - ns := configs.Namespace{Type: nsType} - state.NamespacePaths[ns.Type] = ns.GetPath(pid) - } - } - } - return state, nil -} - -func (c *linuxContainer) currentOCIState() (*specs.State, error) { - bundle, annotations := utils.Annotations(c.config.Labels) - state := &specs.State{ - Version: specs.Version, - ID: c.ID(), - Bundle: bundle, - Annotations: annotations, - } - status, err := c.currentStatus() - if err != nil { - return nil, err - } - state.Status = specs.ContainerState(status.String()) - if status != Stopped { - if c.initProcess != nil { - state.Pid = c.initProcess.pid() - } - } - return state, nil -} - -// orderNamespacePaths sorts namespace paths into a list of paths that we -// can setns in order. -func (c *linuxContainer) orderNamespacePaths(namespaces map[configs.NamespaceType]string) ([]string, error) { - paths := []string{} - for _, ns := range configs.NamespaceTypes() { - - // Remove namespaces that we don't need to join. - if !c.config.Namespaces.Contains(ns) { - continue - } - - if p, ok := namespaces[ns]; ok && p != "" { - // check if the requested namespace is supported - if !configs.IsNamespaceSupported(ns) { - return nil, fmt.Errorf("namespace %s is not supported", ns) - } - // only set to join this namespace if it exists - if _, err := os.Lstat(p); err != nil { - return nil, fmt.Errorf("namespace path: %w", err) - } - // do not allow namespace path with comma as we use it to separate - // the namespace paths - if strings.ContainsRune(p, ',') { - return nil, fmt.Errorf("invalid namespace path %s", p) - } - paths = append(paths, fmt.Sprintf("%s:%s", configs.NsName(ns), p)) - } - - } - - return paths, nil -} - -func encodeIDMapping(idMap []configs.IDMap) ([]byte, error) { - data := bytes.NewBuffer(nil) - for _, im := range idMap { - line := fmt.Sprintf("%d %d %d\n", im.ContainerID, im.HostID, im.Size) - if _, err := data.WriteString(line); err != nil { - return nil, err - } - } - return data.Bytes(), nil -} - -// netlinkError is an error wrapper type for use by custom netlink message -// types. Panics with errors are wrapped in netlinkError so that the recover -// in bootstrapData can distinguish intentional panics. -type netlinkError struct{ error } - -// bootstrapData encodes the necessary data in netlink binary format -// as a io.Reader. -// Consumer can write the data to a bootstrap program -// such as one that uses nsenter package to bootstrap the container's -// init process correctly, i.e. with correct namespaces, uid/gid -// mapping etc. -func (c *linuxContainer) bootstrapData(cloneFlags uintptr, nsMaps map[configs.NamespaceType]string, it initType) (_ io.Reader, Err error) { - // create the netlink message - r := nl.NewNetlinkRequest(int(InitMsg), 0) - - // Our custom messages cannot bubble up an error using returns, instead - // they will panic with the specific error type, netlinkError. In that - // case, recover from the panic and return that as an error. - defer func() { - if r := recover(); r != nil { - if e, ok := r.(netlinkError); ok { - Err = e.error - } else { - panic(r) - } - } - }() - - // write cloneFlags - r.AddData(&Int32msg{ - Type: CloneFlagsAttr, - Value: uint32(cloneFlags), - }) - - // write custom namespace paths - if len(nsMaps) > 0 { - nsPaths, err := c.orderNamespacePaths(nsMaps) - if err != nil { - return nil, err - } - r.AddData(&Bytemsg{ - Type: NsPathsAttr, - Value: []byte(strings.Join(nsPaths, ",")), - }) - } - - // write namespace paths only when we are not joining an existing user ns - _, joinExistingUser := nsMaps[configs.NEWUSER] - if !joinExistingUser { - // write uid mappings - if len(c.config.UidMappings) > 0 { - if c.config.RootlessEUID && c.newuidmapPath != "" { - r.AddData(&Bytemsg{ - Type: UidmapPathAttr, - Value: []byte(c.newuidmapPath), - }) - } - b, err := encodeIDMapping(c.config.UidMappings) - if err != nil { - return nil, err - } - r.AddData(&Bytemsg{ - Type: UidmapAttr, - Value: b, - }) - } - - // write gid mappings - if len(c.config.GidMappings) > 0 { - b, err := encodeIDMapping(c.config.GidMappings) - if err != nil { - return nil, err - } - r.AddData(&Bytemsg{ - Type: GidmapAttr, - Value: b, - }) - if c.config.RootlessEUID && c.newgidmapPath != "" { - r.AddData(&Bytemsg{ - Type: GidmapPathAttr, - Value: []byte(c.newgidmapPath), - }) - } - if requiresRootOrMappingTool(c.config) { - r.AddData(&Boolmsg{ - Type: SetgroupAttr, - Value: true, - }) - } - } - } - - if c.config.OomScoreAdj != nil { - // write oom_score_adj - r.AddData(&Bytemsg{ - Type: OomScoreAdjAttr, - Value: []byte(strconv.Itoa(*c.config.OomScoreAdj)), - }) - } - - // write rootless - r.AddData(&Boolmsg{ - Type: RootlessEUIDAttr, - Value: c.config.RootlessEUID, - }) - - // Bind mount source to open. - if it == initStandard && c.shouldSendMountSources() { - var mounts []byte - for _, m := range c.config.Mounts { - if m.IsBind() { - if strings.IndexByte(m.Source, 0) >= 0 { - return nil, fmt.Errorf("mount source string contains null byte: %q", m.Source) - } - mounts = append(mounts, []byte(m.Source)...) - } - mounts = append(mounts, byte(0)) - } - - r.AddData(&Bytemsg{ - Type: MountSourcesAttr, - Value: mounts, - }) - } - - return bytes.NewReader(r.Serialize()), nil -} - -// ignoreTerminateErrors returns nil if the given err matches an error known -// to indicate that the terminate occurred successfully or err was nil, otherwise -// err is returned unaltered. -func ignoreTerminateErrors(err error) error { - if err == nil { - return nil - } - // terminate() might return an error from either Kill or Wait. - // The (*Cmd).Wait documentation says: "If the command fails to run - // or doesn't complete successfully, the error is of type *ExitError". - // Filter out such errors (like "exit status 1" or "signal: killed"). - var exitErr *exec.ExitError - if errors.As(err, &exitErr) { - return nil - } - if errors.Is(err, os.ErrProcessDone) { - return nil - } - s := err.Error() - if strings.Contains(s, "Wait was already called") { - return nil - } - return err -} - -func requiresRootOrMappingTool(c *configs.Config) bool { - gidMap := []configs.IDMap{ - {ContainerID: 0, HostID: int64(os.Getegid()), Size: 1}, - } - return !reflect.DeepEqual(c.GidMappings, gidMap) -} diff --git a/vendor/github.com/opencontainers/runc/libcontainer/criu_opts_linux.go b/vendor/github.com/opencontainers/runc/libcontainer/criu_opts_linux.go deleted file mode 100644 index b39476ef352..00000000000 --- a/vendor/github.com/opencontainers/runc/libcontainer/criu_opts_linux.go +++ /dev/null @@ -1,34 +0,0 @@ -package libcontainer - -import criu "github.com/checkpoint-restore/go-criu/v5/rpc" - -type CriuPageServerInfo struct { - Address string // IP address of CRIU page server - Port int32 // port number of CRIU page server -} - -type VethPairName struct { - ContainerInterfaceName string - HostInterfaceName string -} - -type CriuOpts struct { - ImagesDirectory string // directory for storing image files - WorkDirectory string // directory to cd and write logs/pidfiles/stats to - ParentImage string // directory for storing parent image files in pre-dump and dump - LeaveRunning bool // leave container in running state after checkpoint - TcpEstablished bool // checkpoint/restore established TCP connections - ExternalUnixConnections bool // allow external unix connections - ShellJob bool // allow to dump and restore shell jobs - FileLocks bool // handle file locks, for safety - PreDump bool // call criu predump to perform iterative checkpoint - PageServer CriuPageServerInfo // allow to dump to criu page server - VethPairs []VethPairName // pass the veth to criu when restore - ManageCgroupsMode criu.CriuCgMode // dump or restore cgroup mode - EmptyNs uint32 // don't c/r properties for namespace from this mask - AutoDedup bool // auto deduplication for incremental dumps - LazyPages bool // restore memory pages lazily using userfaultfd - StatusFd int // fd for feedback when lazy server is ready - LsmProfile string // LSM profile used to restore the container - LsmMountContext string // LSM mount context value to use during restore -} diff --git a/vendor/github.com/opencontainers/runc/libcontainer/eaccess_go119.go b/vendor/github.com/opencontainers/runc/libcontainer/eaccess_go119.go deleted file mode 100644 index cc1e2079a79..00000000000 --- a/vendor/github.com/opencontainers/runc/libcontainer/eaccess_go119.go +++ /dev/null @@ -1,17 +0,0 @@ -//go:build !go1.20 -// +build !go1.20 - -package libcontainer - -import "golang.org/x/sys/unix" - -func eaccess(path string) error { - // This check is similar to access(2) with X_OK except for - // setuid/setgid binaries where it checks against the effective - // (rather than real) uid and gid. It is not needed in go 1.20 - // and beyond and will be removed later. - - // Relies on code added in https://go-review.googlesource.com/c/sys/+/468877 - // and older CLs linked from there. - return unix.Faccessat(unix.AT_FDCWD, path, unix.X_OK, unix.AT_EACCESS) -} diff --git a/vendor/github.com/opencontainers/runc/libcontainer/eaccess_stub.go b/vendor/github.com/opencontainers/runc/libcontainer/eaccess_stub.go deleted file mode 100644 index 7c049fd7aa0..00000000000 --- a/vendor/github.com/opencontainers/runc/libcontainer/eaccess_stub.go +++ /dev/null @@ -1,10 +0,0 @@ -//go:build go1.20 - -package libcontainer - -func eaccess(path string) error { - // Not needed in Go 1.20+ as the functionality is already in there - // (added by https://go.dev/cl/416115, https://go.dev/cl/414824, - // and fixed in Go 1.20.2 by https://go.dev/cl/469956). - return nil -} diff --git a/vendor/github.com/opencontainers/runc/libcontainer/error.go b/vendor/github.com/opencontainers/runc/libcontainer/error.go deleted file mode 100644 index 510c072264f..00000000000 --- a/vendor/github.com/opencontainers/runc/libcontainer/error.go +++ /dev/null @@ -1,13 +0,0 @@ -package libcontainer - -import "errors" - -var ( - ErrExist = errors.New("container with given ID already exists") - ErrInvalidID = errors.New("invalid container ID format") - ErrNotExist = errors.New("container does not exist") - ErrPaused = errors.New("container paused") - ErrRunning = errors.New("container still running") - ErrNotRunning = errors.New("container not running") - ErrNotPaused = errors.New("container not paused") -) diff --git a/vendor/github.com/opencontainers/runc/libcontainer/factory.go b/vendor/github.com/opencontainers/runc/libcontainer/factory.go deleted file mode 100644 index 9f9e8fc583c..00000000000 --- a/vendor/github.com/opencontainers/runc/libcontainer/factory.go +++ /dev/null @@ -1,30 +0,0 @@ -package libcontainer - -import ( - "github.com/opencontainers/runc/libcontainer/configs" -) - -type Factory interface { - // Creates a new container with the given id and starts the initial process inside it. - // id must be a string containing only letters, digits and underscores and must contain - // between 1 and 1024 characters, inclusive. - // - // The id must not already be in use by an existing container. Containers created using - // a factory with the same path (and filesystem) must have distinct ids. - // - // Returns the new container with a running process. - // - // On error, any partially created container parts are cleaned up (the operation is atomic). - Create(id string, config *configs.Config) (Container, error) - - // Load takes an ID for an existing container and returns the container information - // from the state. This presents a read only view of the container. - Load(id string) (Container, error) - - // StartInitialization is an internal API to libcontainer used during the reexec of the - // container. - StartInitialization() error - - // Type returns info string about factory type (e.g. lxc, libcontainer...) - Type() string -} diff --git a/vendor/github.com/opencontainers/runc/libcontainer/factory_linux.go b/vendor/github.com/opencontainers/runc/libcontainer/factory_linux.go deleted file mode 100644 index 546d0eb000c..00000000000 --- a/vendor/github.com/opencontainers/runc/libcontainer/factory_linux.go +++ /dev/null @@ -1,402 +0,0 @@ -package libcontainer - -import ( - "encoding/json" - "errors" - "fmt" - "os" - "path/filepath" - "regexp" - "runtime/debug" - "strconv" - - securejoin "github.com/cyphar/filepath-securejoin" - "github.com/moby/sys/mountinfo" - "golang.org/x/sys/unix" - - "github.com/opencontainers/runc/libcontainer/cgroups/manager" - "github.com/opencontainers/runc/libcontainer/configs" - "github.com/opencontainers/runc/libcontainer/configs/validate" - "github.com/opencontainers/runc/libcontainer/intelrdt" - "github.com/opencontainers/runc/libcontainer/utils" - "github.com/sirupsen/logrus" -) - -const ( - stateFilename = "state.json" - execFifoFilename = "exec.fifo" -) - -var idRegex = regexp.MustCompile(`^[\w+-\.]+$`) - -// InitArgs returns an options func to configure a LinuxFactory with the -// provided init binary path and arguments. -func InitArgs(args ...string) func(*LinuxFactory) error { - return func(l *LinuxFactory) (err error) { - if len(args) > 0 { - // Resolve relative paths to ensure that its available - // after directory changes. - if args[0], err = filepath.Abs(args[0]); err != nil { - // The only error returned from filepath.Abs is - // the one from os.Getwd, i.e. a system error. - return err - } - } - - l.InitArgs = args - return nil - } -} - -// TmpfsRoot is an option func to mount LinuxFactory.Root to tmpfs. -func TmpfsRoot(l *LinuxFactory) error { - mounted, err := mountinfo.Mounted(l.Root) - if err != nil { - return err - } - if !mounted { - if err := mount("tmpfs", l.Root, "", "tmpfs", 0, ""); err != nil { - return err - } - } - return nil -} - -// CriuPath returns an option func to configure a LinuxFactory with the -// provided criupath -func CriuPath(criupath string) func(*LinuxFactory) error { - return func(l *LinuxFactory) error { - l.CriuPath = criupath - return nil - } -} - -// New returns a linux based container factory based in the root directory and -// configures the factory with the provided option funcs. -func New(root string, options ...func(*LinuxFactory) error) (Factory, error) { - if root != "" { - if err := os.MkdirAll(root, 0o700); err != nil { - return nil, err - } - } - l := &LinuxFactory{ - Root: root, - InitPath: "/proc/self/exe", - InitArgs: []string{os.Args[0], "init"}, - Validator: validate.New(), - CriuPath: "criu", - } - - for _, opt := range options { - if opt == nil { - continue - } - if err := opt(l); err != nil { - return nil, err - } - } - return l, nil -} - -// LinuxFactory implements the default factory interface for linux based systems. -type LinuxFactory struct { - // Root directory for the factory to store state. - Root string - - // InitPath is the path for calling the init responsibilities for spawning - // a container. - InitPath string - - // InitArgs are arguments for calling the init responsibilities for spawning - // a container. - InitArgs []string - - // CriuPath is the path to the criu binary used for checkpoint and restore of - // containers. - CriuPath string - - // New{u,g}idmapPath is the path to the binaries used for mapping with - // rootless containers. - NewuidmapPath string - NewgidmapPath string - - // Validator provides validation to container configurations. - Validator validate.Validator -} - -func (l *LinuxFactory) Create(id string, config *configs.Config) (Container, error) { - if l.Root == "" { - return nil, errors.New("root not set") - } - if err := l.validateID(id); err != nil { - return nil, err - } - if err := l.Validator.Validate(config); err != nil { - return nil, err - } - containerRoot, err := securejoin.SecureJoin(l.Root, id) - if err != nil { - return nil, err - } - if _, err := os.Stat(containerRoot); err == nil { - return nil, ErrExist - } else if !os.IsNotExist(err) { - return nil, err - } - - cm, err := manager.New(config.Cgroups) - if err != nil { - return nil, err - } - - // Check that cgroup does not exist or empty (no processes). - // Note for cgroup v1 this check is not thorough, as there are multiple - // separate hierarchies, while both Exists() and GetAllPids() only use - // one for "devices" controller (assuming others are the same, which is - // probably true in almost all scenarios). Checking all the hierarchies - // would be too expensive. - if cm.Exists() { - pids, err := cm.GetAllPids() - // Reading PIDs can race with cgroups removal, so ignore ENOENT and ENODEV. - if err != nil && !errors.Is(err, os.ErrNotExist) && !errors.Is(err, unix.ENODEV) { - return nil, fmt.Errorf("unable to get cgroup PIDs: %w", err) - } - if len(pids) != 0 { - if config.Cgroups.Systemd { - // systemd cgroup driver can't add a pid to an - // existing systemd unit and will return an - // error anyway, so let's error out early. - return nil, fmt.Errorf("container's cgroup is not empty: %d process(es) found", len(pids)) - } - // TODO: return an error. - logrus.Warnf("container's cgroup is not empty: %d process(es) found", len(pids)) - logrus.Warn("DEPRECATED: running container in a non-empty cgroup won't be supported in runc 1.2; https://github.com/opencontainers/runc/issues/3132") - } - } - - // Check that cgroup is not frozen. Do not use Exists() here - // since in cgroup v1 it only checks "devices" controller. - st, err := cm.GetFreezerState() - if err != nil { - return nil, fmt.Errorf("unable to get cgroup freezer state: %w", err) - } - if st == configs.Frozen { - return nil, errors.New("container's cgroup unexpectedly frozen") - } - - if err := os.MkdirAll(containerRoot, 0o711); err != nil { - return nil, err - } - if err := os.Chown(containerRoot, unix.Geteuid(), unix.Getegid()); err != nil { - return nil, err - } - c := &linuxContainer{ - id: id, - root: containerRoot, - config: config, - initPath: l.InitPath, - initArgs: l.InitArgs, - criuPath: l.CriuPath, - newuidmapPath: l.NewuidmapPath, - newgidmapPath: l.NewgidmapPath, - cgroupManager: cm, - intelRdtManager: intelrdt.NewManager(config, id, ""), - } - c.state = &stoppedState{c: c} - return c, nil -} - -func (l *LinuxFactory) Load(id string) (Container, error) { - if l.Root == "" { - return nil, errors.New("root not set") - } - // when load, we need to check id is valid or not. - if err := l.validateID(id); err != nil { - return nil, err - } - containerRoot, err := securejoin.SecureJoin(l.Root, id) - if err != nil { - return nil, err - } - state, err := l.loadState(containerRoot) - if err != nil { - return nil, err - } - r := &nonChildProcess{ - processPid: state.InitProcessPid, - processStartTime: state.InitProcessStartTime, - fds: state.ExternalDescriptors, - } - cm, err := manager.NewWithPaths(state.Config.Cgroups, state.CgroupPaths) - if err != nil { - return nil, err - } - c := &linuxContainer{ - initProcess: r, - initProcessStartTime: state.InitProcessStartTime, - id: id, - config: &state.Config, - initPath: l.InitPath, - initArgs: l.InitArgs, - criuPath: l.CriuPath, - newuidmapPath: l.NewuidmapPath, - newgidmapPath: l.NewgidmapPath, - cgroupManager: cm, - intelRdtManager: intelrdt.NewManager(&state.Config, id, state.IntelRdtPath), - root: containerRoot, - created: state.Created, - } - c.state = &loadedState{c: c} - if err := c.refreshState(); err != nil { - return nil, err - } - return c, nil -} - -func (l *LinuxFactory) Type() string { - return "libcontainer" -} - -// StartInitialization loads a container by opening the pipe fd from the parent to read the configuration and state -// This is a low level implementation detail of the reexec and should not be consumed externally -func (l *LinuxFactory) StartInitialization() (err error) { - // Get the INITPIPE. - envInitPipe := os.Getenv("_LIBCONTAINER_INITPIPE") - pipefd, err := strconv.Atoi(envInitPipe) - if err != nil { - err = fmt.Errorf("unable to convert _LIBCONTAINER_INITPIPE: %w", err) - logrus.Error(err) - return err - } - pipe := os.NewFile(uintptr(pipefd), "pipe") - defer pipe.Close() - - defer func() { - // We have an error during the initialization of the container's init, - // send it back to the parent process in the form of an initError. - if werr := writeSync(pipe, procError); werr != nil { - fmt.Fprintln(os.Stderr, err) - return - } - if werr := utils.WriteJSON(pipe, &initError{Message: err.Error()}); werr != nil { - fmt.Fprintln(os.Stderr, err) - return - } - }() - - // Only init processes have FIFOFD. - fifofd := -1 - envInitType := os.Getenv("_LIBCONTAINER_INITTYPE") - it := initType(envInitType) - if it == initStandard { - envFifoFd := os.Getenv("_LIBCONTAINER_FIFOFD") - if fifofd, err = strconv.Atoi(envFifoFd); err != nil { - return fmt.Errorf("unable to convert _LIBCONTAINER_FIFOFD: %w", err) - } - } - - var consoleSocket *os.File - if envConsole := os.Getenv("_LIBCONTAINER_CONSOLE"); envConsole != "" { - console, err := strconv.Atoi(envConsole) - if err != nil { - return fmt.Errorf("unable to convert _LIBCONTAINER_CONSOLE: %w", err) - } - consoleSocket = os.NewFile(uintptr(console), "console-socket") - defer consoleSocket.Close() - } - - logPipeFdStr := os.Getenv("_LIBCONTAINER_LOGPIPE") - logPipeFd, err := strconv.Atoi(logPipeFdStr) - if err != nil { - return fmt.Errorf("unable to convert _LIBCONTAINER_LOGPIPE: %w", err) - } - - // Get mount files (O_PATH). - mountFds, err := parseMountFds() - if err != nil { - return err - } - - // clear the current process's environment to clean any libcontainer - // specific env vars. - os.Clearenv() - - defer func() { - if e := recover(); e != nil { - if ee, ok := e.(error); ok { - err = fmt.Errorf("panic from initialization: %w, %s", ee, debug.Stack()) - } else { - err = fmt.Errorf("panic from initialization: %v, %s", e, debug.Stack()) - } - } - }() - - i, err := newContainerInit(it, pipe, consoleSocket, fifofd, logPipeFd, mountFds) - if err != nil { - return err - } - - // If Init succeeds, syscall.Exec will not return, hence none of the defers will be called. - return i.Init() -} - -func (l *LinuxFactory) loadState(root string) (*State, error) { - stateFilePath, err := securejoin.SecureJoin(root, stateFilename) - if err != nil { - return nil, err - } - f, err := os.Open(stateFilePath) - if err != nil { - if os.IsNotExist(err) { - return nil, ErrNotExist - } - return nil, err - } - defer f.Close() - var state *State - if err := json.NewDecoder(f).Decode(&state); err != nil { - return nil, err - } - return state, nil -} - -func (l *LinuxFactory) validateID(id string) error { - if !idRegex.MatchString(id) || string(os.PathSeparator)+id != utils.CleanPath(string(os.PathSeparator)+id) { - return ErrInvalidID - } - - return nil -} - -// NewuidmapPath returns an option func to configure a LinuxFactory with the -// provided .. -func NewuidmapPath(newuidmapPath string) func(*LinuxFactory) error { - return func(l *LinuxFactory) error { - l.NewuidmapPath = newuidmapPath - return nil - } -} - -// NewgidmapPath returns an option func to configure a LinuxFactory with the -// provided .. -func NewgidmapPath(newgidmapPath string) func(*LinuxFactory) error { - return func(l *LinuxFactory) error { - l.NewgidmapPath = newgidmapPath - return nil - } -} - -func parseMountFds() ([]int, error) { - fdsJson := os.Getenv("_LIBCONTAINER_MOUNT_FDS") - if fdsJson == "" { - // Always return the nil slice if no fd is present. - return nil, nil - } - - var mountFds []int - if err := json.Unmarshal([]byte(fdsJson), &mountFds); err != nil { - return nil, fmt.Errorf("Error unmarshalling _LIBCONTAINER_MOUNT_FDS: %w", err) - } - - return mountFds, nil -} diff --git a/vendor/github.com/opencontainers/runc/libcontainer/init_linux.go b/vendor/github.com/opencontainers/runc/libcontainer/init_linux.go deleted file mode 100644 index c849ec6b797..00000000000 --- a/vendor/github.com/opencontainers/runc/libcontainer/init_linux.go +++ /dev/null @@ -1,641 +0,0 @@ -package libcontainer - -import ( - "bytes" - "encoding/json" - "errors" - "fmt" - "io" - "net" - "os" - "path/filepath" - "strings" - "syscall" - "unsafe" - - "github.com/containerd/console" - "github.com/opencontainers/runtime-spec/specs-go" - "github.com/sirupsen/logrus" - "github.com/vishvananda/netlink" - "golang.org/x/sys/unix" - - "github.com/opencontainers/runc/libcontainer/capabilities" - "github.com/opencontainers/runc/libcontainer/cgroups" - "github.com/opencontainers/runc/libcontainer/configs" - "github.com/opencontainers/runc/libcontainer/system" - "github.com/opencontainers/runc/libcontainer/user" - "github.com/opencontainers/runc/libcontainer/utils" -) - -type initType string - -const ( - initSetns initType = "setns" - initStandard initType = "standard" -) - -type pid struct { - Pid int `json:"stage2_pid"` - PidFirstChild int `json:"stage1_pid"` -} - -// network is an internal struct used to setup container networks. -type network struct { - configs.Network - - // TempVethPeerName is a unique temporary veth peer name that was placed into - // the container's namespace. - TempVethPeerName string `json:"temp_veth_peer_name"` -} - -// initConfig is used for transferring parameters from Exec() to Init() -type initConfig struct { - Args []string `json:"args"` - Env []string `json:"env"` - Cwd string `json:"cwd"` - Capabilities *configs.Capabilities `json:"capabilities"` - ProcessLabel string `json:"process_label"` - AppArmorProfile string `json:"apparmor_profile"` - NoNewPrivileges bool `json:"no_new_privileges"` - User string `json:"user"` - AdditionalGroups []string `json:"additional_groups"` - Config *configs.Config `json:"config"` - Networks []*network `json:"network"` - PassedFilesCount int `json:"passed_files_count"` - ContainerId string `json:"containerid"` - Rlimits []configs.Rlimit `json:"rlimits"` - CreateConsole bool `json:"create_console"` - ConsoleWidth uint16 `json:"console_width"` - ConsoleHeight uint16 `json:"console_height"` - RootlessEUID bool `json:"rootless_euid,omitempty"` - RootlessCgroups bool `json:"rootless_cgroups,omitempty"` - SpecState *specs.State `json:"spec_state,omitempty"` - Cgroup2Path string `json:"cgroup2_path,omitempty"` -} - -type initer interface { - Init() error -} - -func newContainerInit(t initType, pipe *os.File, consoleSocket *os.File, fifoFd, logFd int, mountFds []int) (initer, error) { - var config *initConfig - if err := json.NewDecoder(pipe).Decode(&config); err != nil { - return nil, err - } - if err := populateProcessEnvironment(config.Env); err != nil { - return nil, err - } - - // Clean the RLIMIT_NOFILE cache in go runtime. - // Issue: https://github.com/opencontainers/runc/issues/4195 - maybeClearRlimitNofileCache(config.Rlimits) - - switch t { - case initSetns: - // mountFds must be nil in this case. We don't mount while doing runc exec. - if mountFds != nil { - return nil, errors.New("mountFds must be nil. Can't mount while doing runc exec.") - } - - return &linuxSetnsInit{ - pipe: pipe, - consoleSocket: consoleSocket, - config: config, - logFd: logFd, - }, nil - case initStandard: - return &linuxStandardInit{ - pipe: pipe, - consoleSocket: consoleSocket, - parentPid: unix.Getppid(), - config: config, - fifoFd: fifoFd, - logFd: logFd, - mountFds: mountFds, - }, nil - } - return nil, fmt.Errorf("unknown init type %q", t) -} - -// populateProcessEnvironment loads the provided environment variables into the -// current processes's environment. -func populateProcessEnvironment(env []string) error { - for _, pair := range env { - p := strings.SplitN(pair, "=", 2) - if len(p) < 2 { - return errors.New("invalid environment variable: missing '='") - } - name, val := p[0], p[1] - if name == "" { - return errors.New("invalid environment variable: name cannot be empty") - } - if strings.IndexByte(name, 0) >= 0 { - return fmt.Errorf("invalid environment variable %q: name contains nul byte (\\x00)", name) - } - if strings.IndexByte(val, 0) >= 0 { - return fmt.Errorf("invalid environment variable %q: value contains nul byte (\\x00)", name) - } - if err := os.Setenv(name, val); err != nil { - return err - } - } - return nil -} - -// verifyCwd ensures that the current directory is actually inside the mount -// namespace root of the current process. -func verifyCwd() error { - // getcwd(2) on Linux detects if cwd is outside of the rootfs of the - // current mount namespace root, and in that case prefixes "(unreachable)" - // to the returned string. glibc's getcwd(3) and Go's Getwd() both detect - // when this happens and return ENOENT rather than returning a non-absolute - // path. In both cases we can therefore easily detect if we have an invalid - // cwd by checking the return value of getcwd(3). See getcwd(3) for more - // details, and CVE-2024-21626 for the security issue that motivated this - // check. - // - // We have to use unix.Getwd() here because os.Getwd() has a workaround for - // $PWD which involves doing stat(.), which can fail if the current - // directory is inaccessible to the container process. - if wd, err := unix.Getwd(); errors.Is(err, unix.ENOENT) { - return errors.New("current working directory is outside of container mount namespace root -- possible container breakout detected") - } else if err != nil { - return fmt.Errorf("failed to verify if current working directory is safe: %w", err) - } else if !filepath.IsAbs(wd) { - // We shouldn't ever hit this, but check just in case. - return fmt.Errorf("current working directory is not absolute -- possible container breakout detected: cwd is %q", wd) - } - return nil -} - -// finalizeNamespace drops the caps, sets the correct user -// and working dir, and closes any leaked file descriptors -// before executing the command inside the namespace -func finalizeNamespace(config *initConfig) error { - // Ensure that all unwanted fds we may have accidentally - // inherited are marked close-on-exec so they stay out of the - // container - if err := utils.CloseExecFrom(config.PassedFilesCount + 3); err != nil { - return fmt.Errorf("error closing exec fds: %w", err) - } - - // we only do chdir if it's specified - doChdir := config.Cwd != "" - if doChdir { - // First, attempt the chdir before setting up the user. - // This could allow us to access a directory that the user running runc can access - // but the container user cannot. - err := unix.Chdir(config.Cwd) - switch { - case err == nil: - doChdir = false - case os.IsPermission(err): - // If we hit an EPERM, we should attempt again after setting up user. - // This will allow us to successfully chdir if the container user has access - // to the directory, but the user running runc does not. - // This is useful in cases where the cwd is also a volume that's been chowned to the container user. - default: - return fmt.Errorf("chdir to cwd (%q) set in config.json failed: %w", config.Cwd, err) - } - } - - caps := &configs.Capabilities{} - if config.Capabilities != nil { - caps = config.Capabilities - } else if config.Config.Capabilities != nil { - caps = config.Config.Capabilities - } - w, err := capabilities.New(caps) - if err != nil { - return err - } - // drop capabilities in bounding set before changing user - if err := w.ApplyBoundingSet(); err != nil { - return fmt.Errorf("unable to apply bounding set: %w", err) - } - // preserve existing capabilities while we change users - if err := system.SetKeepCaps(); err != nil { - return fmt.Errorf("unable to set keep caps: %w", err) - } - if err := setupUser(config); err != nil { - return fmt.Errorf("unable to setup user: %w", err) - } - // Change working directory AFTER the user has been set up, if we haven't done it yet. - if doChdir { - if err := unix.Chdir(config.Cwd); err != nil { - return fmt.Errorf("chdir to cwd (%q) set in config.json failed: %w", config.Cwd, err) - } - } - // Make sure our final working directory is inside the container. - if err := verifyCwd(); err != nil { - return err - } - if err := system.ClearKeepCaps(); err != nil { - return fmt.Errorf("unable to clear keep caps: %w", err) - } - if err := w.ApplyCaps(); err != nil { - return fmt.Errorf("unable to apply caps: %w", err) - } - return nil -} - -// setupConsole sets up the console from inside the container, and sends the -// master pty fd to the config.Pipe (using cmsg). This is done to ensure that -// consoles are scoped to a container properly (see runc#814 and the many -// issues related to that). This has to be run *after* we've pivoted to the new -// rootfs (and the users' configuration is entirely set up). -func setupConsole(socket *os.File, config *initConfig, mount bool) error { - defer socket.Close() - // At this point, /dev/ptmx points to something that we would expect. We - // used to change the owner of the slave path, but since the /dev/pts mount - // can have gid=X set (at the users' option). So touching the owner of the - // slave PTY is not necessary, as the kernel will handle that for us. Note - // however, that setupUser (specifically fixStdioPermissions) *will* change - // the UID owner of the console to be the user the process will run as (so - // they can actually control their console). - - pty, slavePath, err := console.NewPty() - if err != nil { - return err - } - - // After we return from here, we don't need the console anymore. - defer pty.Close() - - if config.ConsoleHeight != 0 && config.ConsoleWidth != 0 { - err = pty.Resize(console.WinSize{ - Height: config.ConsoleHeight, - Width: config.ConsoleWidth, - }) - if err != nil { - return err - } - } - - // Mount the console inside our rootfs. - if mount { - if err := mountConsole(slavePath); err != nil { - return err - } - } - // While we can access console.master, using the API is a good idea. - if err := utils.SendFd(socket, pty.Name(), pty.Fd()); err != nil { - return err - } - // Now, dup over all the things. - return dupStdio(slavePath) -} - -// syncParentReady sends to the given pipe a JSON payload which indicates that -// the init is ready to Exec the child process. It then waits for the parent to -// indicate that it is cleared to Exec. -func syncParentReady(pipe io.ReadWriter) error { - // Tell parent. - if err := writeSync(pipe, procReady); err != nil { - return err - } - - // Wait for parent to give the all-clear. - return readSync(pipe, procRun) -} - -// syncParentHooks sends to the given pipe a JSON payload which indicates that -// the parent should execute pre-start hooks. It then waits for the parent to -// indicate that it is cleared to resume. -func syncParentHooks(pipe io.ReadWriter) error { - // Tell parent. - if err := writeSync(pipe, procHooks); err != nil { - return err - } - - // Wait for parent to give the all-clear. - return readSync(pipe, procResume) -} - -// syncParentSeccomp sends to the given pipe a JSON payload which -// indicates that the parent should pick up the seccomp fd with pidfd_getfd() -// and send it to the seccomp agent over a unix socket. It then waits for -// the parent to indicate that it is cleared to resume and closes the seccompFd. -// If the seccompFd is -1, there isn't anything to sync with the parent, so it -// returns no error. -func syncParentSeccomp(pipe io.ReadWriter, seccompFd int) error { - if seccompFd == -1 { - return nil - } - - // Tell parent. - if err := writeSyncWithFd(pipe, procSeccomp, seccompFd); err != nil { - unix.Close(seccompFd) - return err - } - - // Wait for parent to give the all-clear. - if err := readSync(pipe, procSeccompDone); err != nil { - unix.Close(seccompFd) - return fmt.Errorf("sync parent seccomp: %w", err) - } - - if err := unix.Close(seccompFd); err != nil { - return fmt.Errorf("close seccomp fd: %w", err) - } - - return nil -} - -// setupUser changes the groups, gid, and uid for the user inside the container -func setupUser(config *initConfig) error { - // Set up defaults. - defaultExecUser := user.ExecUser{ - Uid: 0, - Gid: 0, - Home: "/", - } - - passwdPath, err := user.GetPasswdPath() - if err != nil { - return err - } - - groupPath, err := user.GetGroupPath() - if err != nil { - return err - } - - execUser, err := user.GetExecUserPath(config.User, &defaultExecUser, passwdPath, groupPath) - if err != nil { - return err - } - - var addGroups []int - if len(config.AdditionalGroups) > 0 { - addGroups, err = user.GetAdditionalGroupsPath(config.AdditionalGroups, groupPath) - if err != nil { - return err - } - } - - // Rather than just erroring out later in setuid(2) and setgid(2), check - // that the user is mapped here. - if _, err := config.Config.HostUID(execUser.Uid); err != nil { - return errors.New("cannot set uid to unmapped user in user namespace") - } - if _, err := config.Config.HostGID(execUser.Gid); err != nil { - return errors.New("cannot set gid to unmapped user in user namespace") - } - - if config.RootlessEUID { - // We cannot set any additional groups in a rootless container and thus - // we bail if the user asked us to do so. TODO: We currently can't do - // this check earlier, but if libcontainer.Process.User was typesafe - // this might work. - if len(addGroups) > 0 { - return errors.New("cannot set any additional groups in a rootless container") - } - } - - // Before we change to the container's user make sure that the processes - // STDIO is correctly owned by the user that we are switching to. - if err := fixStdioPermissions(execUser); err != nil { - return err - } - - setgroups, err := os.ReadFile("/proc/self/setgroups") - if err != nil && !os.IsNotExist(err) { - return err - } - - // This isn't allowed in an unprivileged user namespace since Linux 3.19. - // There's nothing we can do about /etc/group entries, so we silently - // ignore setting groups here (since the user didn't explicitly ask us to - // set the group). - allowSupGroups := !config.RootlessEUID && string(bytes.TrimSpace(setgroups)) != "deny" - - if allowSupGroups { - suppGroups := append(execUser.Sgids, addGroups...) - if err := unix.Setgroups(suppGroups); err != nil { - return &os.SyscallError{Syscall: "setgroups", Err: err} - } - } - - if err := system.Setgid(execUser.Gid); err != nil { - return err - } - if err := system.Setuid(execUser.Uid); err != nil { - return err - } - - // if we didn't get HOME already, set it based on the user's HOME - if envHome := os.Getenv("HOME"); envHome == "" { - if err := os.Setenv("HOME", execUser.Home); err != nil { - return err - } - } - return nil -} - -// fixStdioPermissions fixes the permissions of PID 1's STDIO within the container to the specified user. -// The ownership needs to match because it is created outside of the container and needs to be -// localized. -func fixStdioPermissions(u *user.ExecUser) error { - var null unix.Stat_t - if err := unix.Stat("/dev/null", &null); err != nil { - return &os.PathError{Op: "stat", Path: "/dev/null", Err: err} - } - for _, file := range []*os.File{os.Stdin, os.Stdout, os.Stderr} { - var s unix.Stat_t - if err := unix.Fstat(int(file.Fd()), &s); err != nil { - return &os.PathError{Op: "fstat", Path: file.Name(), Err: err} - } - - // Skip chown if uid is already the one we want or any of the STDIO descriptors - // were redirected to /dev/null. - if int(s.Uid) == u.Uid || s.Rdev == null.Rdev { - continue - } - - // We only change the uid (as it is possible for the mount to - // prefer a different gid, and there's no reason for us to change it). - // The reason why we don't just leave the default uid=X mount setup is - // that users expect to be able to actually use their console. Without - // this code, you couldn't effectively run as a non-root user inside a - // container and also have a console set up. - if err := file.Chown(u.Uid, int(s.Gid)); err != nil { - // If we've hit an EINVAL then s.Gid isn't mapped in the user - // namespace. If we've hit an EPERM then the inode's current owner - // is not mapped in our user namespace (in particular, - // privileged_wrt_inode_uidgid() has failed). Read-only - // /dev can result in EROFS error. In any case, it's - // better for us to just not touch the stdio rather - // than bail at this point. - - if errors.Is(err, unix.EINVAL) || errors.Is(err, unix.EPERM) || errors.Is(err, unix.EROFS) { - continue - } - return err - } - } - return nil -} - -// setupNetwork sets up and initializes any network interface inside the container. -func setupNetwork(config *initConfig) error { - for _, config := range config.Networks { - strategy, err := getStrategy(config.Type) - if err != nil { - return err - } - if err := strategy.initialize(config); err != nil { - return err - } - } - return nil -} - -func setupRoute(config *configs.Config) error { - for _, config := range config.Routes { - _, dst, err := net.ParseCIDR(config.Destination) - if err != nil { - return err - } - src := net.ParseIP(config.Source) - if src == nil { - return fmt.Errorf("Invalid source for route: %s", config.Source) - } - gw := net.ParseIP(config.Gateway) - if gw == nil { - return fmt.Errorf("Invalid gateway for route: %s", config.Gateway) - } - l, err := netlink.LinkByName(config.InterfaceName) - if err != nil { - return err - } - route := &netlink.Route{ - Scope: netlink.SCOPE_UNIVERSE, - Dst: dst, - Src: src, - Gw: gw, - LinkIndex: l.Attrs().Index, - } - if err := netlink.RouteAdd(route); err != nil { - return err - } - } - return nil -} - -func maybeClearRlimitNofileCache(limits []configs.Rlimit) { - for _, rlimit := range limits { - if rlimit.Type == syscall.RLIMIT_NOFILE { - system.ClearRlimitNofileCache(&syscall.Rlimit{ - Cur: rlimit.Soft, - Max: rlimit.Hard, - }) - return - } - } -} - -func setupRlimits(limits []configs.Rlimit, pid int) error { - for _, rlimit := range limits { - if err := unix.Prlimit(pid, rlimit.Type, &unix.Rlimit{Max: rlimit.Hard, Cur: rlimit.Soft}, nil); err != nil { - return fmt.Errorf("error setting rlimit type %v: %w", rlimit.Type, err) - } - } - return nil -} - -const _P_PID = 1 - -//nolint:structcheck,unused -type siginfo struct { - si_signo int32 - si_errno int32 - si_code int32 - // below here is a union; si_pid is the only field we use - si_pid int32 - // Pad to 128 bytes as detailed in blockUntilWaitable - pad [96]byte -} - -// isWaitable returns true if the process has exited false otherwise. -// Its based off blockUntilWaitable in src/os/wait_waitid.go -func isWaitable(pid int) (bool, error) { - si := &siginfo{} - _, _, e := unix.Syscall6(unix.SYS_WAITID, _P_PID, uintptr(pid), uintptr(unsafe.Pointer(si)), unix.WEXITED|unix.WNOWAIT|unix.WNOHANG, 0, 0) - if e != 0 { - return false, &os.SyscallError{Syscall: "waitid", Err: e} - } - - return si.si_pid != 0, nil -} - -// signalAllProcesses freezes then iterates over all the processes inside the -// manager's cgroups sending the signal s to them. -// If s is SIGKILL then it will wait for each process to exit. -// For all other signals it will check if the process is ready to report its -// exit status and only if it is will a wait be performed. -func signalAllProcesses(m cgroups.Manager, s os.Signal) error { - var procs []*os.Process - if err := m.Freeze(configs.Frozen); err != nil { - logrus.Warn(err) - } - pids, err := m.GetAllPids() - if err != nil { - if err := m.Freeze(configs.Thawed); err != nil { - logrus.Warn(err) - } - return err - } - for _, pid := range pids { - p, err := os.FindProcess(pid) - if err != nil { - logrus.Warn(err) - continue - } - procs = append(procs, p) - if err := p.Signal(s); err != nil { - logrus.Warn(err) - } - } - if err := m.Freeze(configs.Thawed); err != nil { - logrus.Warn(err) - } - - subreaper, err := system.GetSubreaper() - if err != nil { - // The error here means that PR_GET_CHILD_SUBREAPER is not - // supported because this code might run on a kernel older - // than 3.4. We don't want to throw an error in that case, - // and we simplify things, considering there is no subreaper - // set. - subreaper = 0 - } - - for _, p := range procs { - if s != unix.SIGKILL { - if ok, err := isWaitable(p.Pid); err != nil { - if !errors.Is(err, unix.ECHILD) { - logrus.Warn("signalAllProcesses: ", p.Pid, err) - } - continue - } else if !ok { - // Not ready to report so don't wait - continue - } - } - - // In case a subreaper has been setup, this code must not - // wait for the process. Otherwise, we cannot be sure the - // current process will be reaped by the subreaper, while - // the subreaper might be waiting for this process in order - // to retrieve its exit code. - if subreaper == 0 { - if _, err := p.Wait(); err != nil { - if !errors.Is(err, unix.ECHILD) { - logrus.Warn("wait: ", err) - } - } - } - } - return nil -} diff --git a/vendor/github.com/opencontainers/runc/libcontainer/keys/keyctl.go b/vendor/github.com/opencontainers/runc/libcontainer/keys/keyctl.go deleted file mode 100644 index f3a6c5343fa..00000000000 --- a/vendor/github.com/opencontainers/runc/libcontainer/keys/keyctl.go +++ /dev/null @@ -1,45 +0,0 @@ -package keys - -import ( - "errors" - "fmt" - "strconv" - "strings" - - "golang.org/x/sys/unix" -) - -type KeySerial uint32 - -func JoinSessionKeyring(name string) (KeySerial, error) { - sessKeyID, err := unix.KeyctlJoinSessionKeyring(name) - if err != nil { - return 0, fmt.Errorf("unable to create session key: %w", err) - } - return KeySerial(sessKeyID), nil -} - -// ModKeyringPerm modifies permissions on a keyring by reading the current permissions, -// anding the bits with the given mask (clearing permissions) and setting -// additional permission bits -func ModKeyringPerm(ringID KeySerial, mask, setbits uint32) error { - dest, err := unix.KeyctlString(unix.KEYCTL_DESCRIBE, int(ringID)) - if err != nil { - return err - } - - res := strings.Split(dest, ";") - if len(res) < 5 { - return errors.New("Destination buffer for key description is too small") - } - - // parse permissions - perm64, err := strconv.ParseUint(res[3], 16, 32) - if err != nil { - return err - } - - perm := (uint32(perm64) & mask) | setbits - - return unix.KeyctlSetperm(int(ringID), perm) -} diff --git a/vendor/github.com/opencontainers/runc/libcontainer/logs/logs.go b/vendor/github.com/opencontainers/runc/libcontainer/logs/logs.go deleted file mode 100644 index 95deb0d6ca7..00000000000 --- a/vendor/github.com/opencontainers/runc/libcontainer/logs/logs.go +++ /dev/null @@ -1,56 +0,0 @@ -package logs - -import ( - "bufio" - "encoding/json" - "io" - - "github.com/sirupsen/logrus" -) - -func ForwardLogs(logPipe io.ReadCloser) chan error { - done := make(chan error, 1) - s := bufio.NewScanner(logPipe) - - logger := logrus.StandardLogger() - if logger.ReportCaller { - // Need a copy of the standard logger, but with ReportCaller - // turned off, as the logs are merely forwarded and their - // true source is not this file/line/function. - logNoCaller := *logrus.StandardLogger() - logNoCaller.ReportCaller = false - logger = &logNoCaller - } - - go func() { - for s.Scan() { - processEntry(s.Bytes(), logger) - } - if err := logPipe.Close(); err != nil { - logrus.Errorf("error closing log source: %v", err) - } - // The only error we want to return is when reading from - // logPipe has failed. - done <- s.Err() - close(done) - }() - - return done -} - -func processEntry(text []byte, logger *logrus.Logger) { - if len(text) == 0 { - return - } - - var jl struct { - Level logrus.Level `json:"level"` - Msg string `json:"msg"` - } - if err := json.Unmarshal(text, &jl); err != nil { - logrus.Errorf("failed to decode %q to json: %v", text, err) - return - } - - logger.Log(jl.Level, jl.Msg) -} diff --git a/vendor/github.com/opencontainers/runc/libcontainer/message_linux.go b/vendor/github.com/opencontainers/runc/libcontainer/message_linux.go deleted file mode 100644 index 6d1107e875d..00000000000 --- a/vendor/github.com/opencontainers/runc/libcontainer/message_linux.go +++ /dev/null @@ -1,97 +0,0 @@ -package libcontainer - -import ( - "fmt" - "math" - - "github.com/vishvananda/netlink/nl" - "golang.org/x/sys/unix" -) - -// list of known message types we want to send to bootstrap program -// The number is randomly chosen to not conflict with known netlink types -const ( - InitMsg uint16 = 62000 - CloneFlagsAttr uint16 = 27281 - NsPathsAttr uint16 = 27282 - UidmapAttr uint16 = 27283 - GidmapAttr uint16 = 27284 - SetgroupAttr uint16 = 27285 - OomScoreAdjAttr uint16 = 27286 - RootlessEUIDAttr uint16 = 27287 - UidmapPathAttr uint16 = 27288 - GidmapPathAttr uint16 = 27289 - MountSourcesAttr uint16 = 27290 -) - -type Int32msg struct { - Type uint16 - Value uint32 -} - -// Serialize serializes the message. -// Int32msg has the following representation -// | nlattr len | nlattr type | -// | uint32 value | -func (msg *Int32msg) Serialize() []byte { - buf := make([]byte, msg.Len()) - native := nl.NativeEndian() - native.PutUint16(buf[0:2], uint16(msg.Len())) - native.PutUint16(buf[2:4], msg.Type) - native.PutUint32(buf[4:8], msg.Value) - return buf -} - -func (msg *Int32msg) Len() int { - return unix.NLA_HDRLEN + 4 -} - -// Bytemsg has the following representation -// | nlattr len | nlattr type | -// | value | pad | -type Bytemsg struct { - Type uint16 - Value []byte -} - -func (msg *Bytemsg) Serialize() []byte { - l := msg.Len() - if l > math.MaxUint16 { - // We cannot return nil nor an error here, so we panic with - // a specific type instead, which is handled via recover in - // bootstrapData. - panic(netlinkError{fmt.Errorf("netlink: cannot serialize bytemsg of length %d (larger than UINT16_MAX)", l)}) - } - buf := make([]byte, (l+unix.NLA_ALIGNTO-1) & ^(unix.NLA_ALIGNTO-1)) - native := nl.NativeEndian() - native.PutUint16(buf[0:2], uint16(l)) - native.PutUint16(buf[2:4], msg.Type) - copy(buf[4:], msg.Value) - return buf -} - -func (msg *Bytemsg) Len() int { - return unix.NLA_HDRLEN + len(msg.Value) + 1 // null-terminated -} - -type Boolmsg struct { - Type uint16 - Value bool -} - -func (msg *Boolmsg) Serialize() []byte { - buf := make([]byte, msg.Len()) - native := nl.NativeEndian() - native.PutUint16(buf[0:2], uint16(msg.Len())) - native.PutUint16(buf[2:4], msg.Type) - if msg.Value { - native.PutUint32(buf[4:8], uint32(1)) - } else { - native.PutUint32(buf[4:8], uint32(0)) - } - return buf -} - -func (msg *Boolmsg) Len() int { - return unix.NLA_HDRLEN + 4 // alignment -} diff --git a/vendor/github.com/opencontainers/runc/libcontainer/mount_linux.go b/vendor/github.com/opencontainers/runc/libcontainer/mount_linux.go deleted file mode 100644 index 948b6c0b48b..00000000000 --- a/vendor/github.com/opencontainers/runc/libcontainer/mount_linux.go +++ /dev/null @@ -1,101 +0,0 @@ -package libcontainer - -import ( - "io/fs" - "strconv" - - "golang.org/x/sys/unix" -) - -// mountError holds an error from a failed mount or unmount operation. -type mountError struct { - op string - source string - target string - procfd string - flags uintptr - data string - err error -} - -// Error provides a string error representation. -func (e *mountError) Error() string { - out := e.op + " " - - if e.source != "" { - out += e.source + ":" + e.target - } else { - out += e.target - } - if e.procfd != "" { - out += " (via " + e.procfd + ")" - } - - if e.flags != uintptr(0) { - out += ", flags: 0x" + strconv.FormatUint(uint64(e.flags), 16) - } - if e.data != "" { - out += ", data: " + e.data - } - - out += ": " + e.err.Error() - return out -} - -// Unwrap returns the underlying error. -// This is a convention used by Go 1.13+ standard library. -func (e *mountError) Unwrap() error { - return e.err -} - -// mount is a simple unix.Mount wrapper. If procfd is not empty, it is used -// instead of target (and the target is only used to add context to an error). -func mount(source, target, procfd, fstype string, flags uintptr, data string) error { - dst := target - if procfd != "" { - dst = procfd - } - if err := unix.Mount(source, dst, fstype, flags, data); err != nil { - return &mountError{ - op: "mount", - source: source, - target: target, - procfd: procfd, - flags: flags, - data: data, - err: err, - } - } - return nil -} - -// unmount is a simple unix.Unmount wrapper. -func unmount(target string, flags int) error { - err := unix.Unmount(target, flags) - if err != nil { - return &mountError{ - op: "unmount", - target: target, - flags: uintptr(flags), - err: err, - } - } - return nil -} - -// syscallMode returns the syscall-specific mode bits from Go's portable mode bits. -// Copy from https://cs.opensource.google/go/go/+/refs/tags/go1.20.7:src/os/file_posix.go;l=61-75 -func syscallMode(i fs.FileMode) (o uint32) { - o |= uint32(i.Perm()) - if i&fs.ModeSetuid != 0 { - o |= unix.S_ISUID - } - if i&fs.ModeSetgid != 0 { - o |= unix.S_ISGID - } - if i&fs.ModeSticky != 0 { - o |= unix.S_ISVTX - } - // No mapping for Go's ModeTemporary (plan9 only). - return -} diff --git a/vendor/github.com/opencontainers/runc/libcontainer/network_linux.go b/vendor/github.com/opencontainers/runc/libcontainer/network_linux.go deleted file mode 100644 index 8915548b3bc..00000000000 --- a/vendor/github.com/opencontainers/runc/libcontainer/network_linux.go +++ /dev/null @@ -1,100 +0,0 @@ -package libcontainer - -import ( - "bytes" - "fmt" - "os" - "path/filepath" - "strconv" - - "github.com/opencontainers/runc/libcontainer/configs" - "github.com/opencontainers/runc/types" - "github.com/vishvananda/netlink" -) - -var strategies = map[string]networkStrategy{ - "loopback": &loopback{}, -} - -// networkStrategy represents a specific network configuration for -// a container's networking stack -type networkStrategy interface { - create(*network, int) error - initialize(*network) error - detach(*configs.Network) error - attach(*configs.Network) error -} - -// getStrategy returns the specific network strategy for the -// provided type. -func getStrategy(tpe string) (networkStrategy, error) { - s, exists := strategies[tpe] - if !exists { - return nil, fmt.Errorf("unknown strategy type %q", tpe) - } - return s, nil -} - -// Returns the network statistics for the network interfaces represented by the NetworkRuntimeInfo. -func getNetworkInterfaceStats(interfaceName string) (*types.NetworkInterface, error) { - out := &types.NetworkInterface{Name: interfaceName} - // This can happen if the network runtime information is missing - possible if the - // container was created by an old version of libcontainer. - if interfaceName == "" { - return out, nil - } - type netStatsPair struct { - // Where to write the output. - Out *uint64 - // The network stats file to read. - File string - } - // Ingress for host veth is from the container. Hence tx_bytes stat on the host veth is actually number of bytes received by the container. - netStats := []netStatsPair{ - {Out: &out.RxBytes, File: "tx_bytes"}, - {Out: &out.RxPackets, File: "tx_packets"}, - {Out: &out.RxErrors, File: "tx_errors"}, - {Out: &out.RxDropped, File: "tx_dropped"}, - - {Out: &out.TxBytes, File: "rx_bytes"}, - {Out: &out.TxPackets, File: "rx_packets"}, - {Out: &out.TxErrors, File: "rx_errors"}, - {Out: &out.TxDropped, File: "rx_dropped"}, - } - for _, netStat := range netStats { - data, err := readSysfsNetworkStats(interfaceName, netStat.File) - if err != nil { - return nil, err - } - *(netStat.Out) = data - } - return out, nil -} - -// Reads the specified statistics available under /sys/class/net//statistics -func readSysfsNetworkStats(ethInterface, statsFile string) (uint64, error) { - data, err := os.ReadFile(filepath.Join("/sys/class/net", ethInterface, "statistics", statsFile)) - if err != nil { - return 0, err - } - return strconv.ParseUint(string(bytes.TrimSpace(data)), 10, 64) -} - -// loopback is a network strategy that provides a basic loopback device -type loopback struct{} - -func (l *loopback) create(n *network, nspid int) error { - return nil -} - -func (l *loopback) initialize(config *network) error { - return netlink.LinkSetUp(&netlink.Device{LinkAttrs: netlink.LinkAttrs{Name: "lo"}}) -} - -func (l *loopback) attach(n *configs.Network) (err error) { - return nil -} - -func (l *loopback) detach(n *configs.Network) (err error) { - return nil -} diff --git a/vendor/github.com/opencontainers/runc/libcontainer/notify_linux.go b/vendor/github.com/opencontainers/runc/libcontainer/notify_linux.go deleted file mode 100644 index a8762842e8f..00000000000 --- a/vendor/github.com/opencontainers/runc/libcontainer/notify_linux.go +++ /dev/null @@ -1,84 +0,0 @@ -package libcontainer - -import ( - "errors" - "fmt" - "os" - "path/filepath" - - "golang.org/x/sys/unix" -) - -type PressureLevel uint - -const ( - LowPressure PressureLevel = iota - MediumPressure - CriticalPressure -) - -func registerMemoryEvent(cgDir string, evName string, arg string) (<-chan struct{}, error) { - evFile, err := os.Open(filepath.Join(cgDir, evName)) - if err != nil { - return nil, err - } - fd, err := unix.Eventfd(0, unix.EFD_CLOEXEC) - if err != nil { - evFile.Close() - return nil, err - } - - eventfd := os.NewFile(uintptr(fd), "eventfd") - - eventControlPath := filepath.Join(cgDir, "cgroup.event_control") - data := fmt.Sprintf("%d %d %s", eventfd.Fd(), evFile.Fd(), arg) - if err := os.WriteFile(eventControlPath, []byte(data), 0o700); err != nil { - eventfd.Close() - evFile.Close() - return nil, err - } - ch := make(chan struct{}) - go func() { - defer func() { - eventfd.Close() - evFile.Close() - close(ch) - }() - buf := make([]byte, 8) - for { - if _, err := eventfd.Read(buf); err != nil { - return - } - // When a cgroup is destroyed, an event is sent to eventfd. - // So if the control path is gone, return instead of notifying. - if _, err := os.Lstat(eventControlPath); os.IsNotExist(err) { - return - } - ch <- struct{}{} - } - }() - return ch, nil -} - -// notifyOnOOM returns channel on which you can expect event about OOM, -// if process died without OOM this channel will be closed. -func notifyOnOOM(dir string) (<-chan struct{}, error) { - if dir == "" { - return nil, errors.New("memory controller missing") - } - - return registerMemoryEvent(dir, "memory.oom_control", "") -} - -func notifyMemoryPressure(dir string, level PressureLevel) (<-chan struct{}, error) { - if dir == "" { - return nil, errors.New("memory controller missing") - } - - if level > CriticalPressure { - return nil, fmt.Errorf("invalid pressure level %d", level) - } - - levelStr := []string{"low", "medium", "critical"}[level] - return registerMemoryEvent(dir, "memory.pressure_level", levelStr) -} diff --git a/vendor/github.com/opencontainers/runc/libcontainer/notify_v2_linux.go b/vendor/github.com/opencontainers/runc/libcontainer/notify_v2_linux.go deleted file mode 100644 index 821536c8da0..00000000000 --- a/vendor/github.com/opencontainers/runc/libcontainer/notify_v2_linux.go +++ /dev/null @@ -1,80 +0,0 @@ -package libcontainer - -import ( - "fmt" - "path/filepath" - "unsafe" - - "github.com/opencontainers/runc/libcontainer/cgroups/fscommon" - "github.com/sirupsen/logrus" - "golang.org/x/sys/unix" -) - -func registerMemoryEventV2(cgDir, evName, cgEvName string) (<-chan struct{}, error) { - fd, err := unix.InotifyInit() - if err != nil { - return nil, fmt.Errorf("unable to init inotify: %w", err) - } - // watching oom kill - evFd, err := unix.InotifyAddWatch(fd, filepath.Join(cgDir, evName), unix.IN_MODIFY) - if err != nil { - unix.Close(fd) - return nil, fmt.Errorf("unable to add inotify watch: %w", err) - } - // Because no `unix.IN_DELETE|unix.IN_DELETE_SELF` event for cgroup file system, so watching all process exited - cgFd, err := unix.InotifyAddWatch(fd, filepath.Join(cgDir, cgEvName), unix.IN_MODIFY) - if err != nil { - unix.Close(fd) - return nil, fmt.Errorf("unable to add inotify watch: %w", err) - } - ch := make(chan struct{}) - go func() { - var ( - buffer [unix.SizeofInotifyEvent + unix.PathMax + 1]byte - offset uint32 - ) - defer func() { - unix.Close(fd) - close(ch) - }() - - for { - n, err := unix.Read(fd, buffer[:]) - if err != nil { - logrus.Warnf("unable to read event data from inotify, got error: %v", err) - return - } - if n < unix.SizeofInotifyEvent { - logrus.Warnf("we should read at least %d bytes from inotify, but got %d bytes.", unix.SizeofInotifyEvent, n) - return - } - offset = 0 - for offset <= uint32(n-unix.SizeofInotifyEvent) { - rawEvent := (*unix.InotifyEvent)(unsafe.Pointer(&buffer[offset])) - offset += unix.SizeofInotifyEvent + rawEvent.Len - if rawEvent.Mask&unix.IN_MODIFY != unix.IN_MODIFY { - continue - } - switch int(rawEvent.Wd) { - case evFd: - oom, err := fscommon.GetValueByKey(cgDir, evName, "oom_kill") - if err != nil || oom > 0 { - ch <- struct{}{} - } - case cgFd: - pids, err := fscommon.GetValueByKey(cgDir, cgEvName, "populated") - if err != nil || pids == 0 { - return - } - } - } - } - }() - return ch, nil -} - -// notifyOnOOMV2 returns channel on which you can expect event about OOM, -// if process died without OOM this channel will be closed. -func notifyOnOOMV2(path string) (<-chan struct{}, error) { - return registerMemoryEventV2(path, "memory.events", "cgroup.events") -} diff --git a/vendor/github.com/opencontainers/runc/libcontainer/process.go b/vendor/github.com/opencontainers/runc/libcontainer/process.go deleted file mode 100644 index 8a5d340dacd..00000000000 --- a/vendor/github.com/opencontainers/runc/libcontainer/process.go +++ /dev/null @@ -1,126 +0,0 @@ -package libcontainer - -import ( - "errors" - "io" - "math" - "os" - - "github.com/opencontainers/runc/libcontainer/configs" -) - -var errInvalidProcess = errors.New("invalid process") - -type processOperations interface { - wait() (*os.ProcessState, error) - signal(sig os.Signal) error - pid() int -} - -// Process specifies the configuration and IO for a process inside -// a container. -type Process struct { - // The command to be run followed by any arguments. - Args []string - - // Env specifies the environment variables for the process. - Env []string - - // User will set the uid and gid of the executing process running inside the container - // local to the container's user and group configuration. - User string - - // AdditionalGroups specifies the gids that should be added to supplementary groups - // in addition to those that the user belongs to. - AdditionalGroups []string - - // Cwd will change the processes current working directory inside the container's rootfs. - Cwd string - - // Stdin is a pointer to a reader which provides the standard input stream. - Stdin io.Reader - - // Stdout is a pointer to a writer which receives the standard output stream. - Stdout io.Writer - - // Stderr is a pointer to a writer which receives the standard error stream. - Stderr io.Writer - - // ExtraFiles specifies additional open files to be inherited by the container - ExtraFiles []*os.File - - // Initial sizings for the console - ConsoleWidth uint16 - ConsoleHeight uint16 - - // Capabilities specify the capabilities to keep when executing the process inside the container - // All capabilities not specified will be dropped from the processes capability mask - Capabilities *configs.Capabilities - - // AppArmorProfile specifies the profile to apply to the process and is - // changed at the time the process is execed - AppArmorProfile string - - // Label specifies the label to apply to the process. It is commonly used by selinux - Label string - - // NoNewPrivileges controls whether processes can gain additional privileges. - NoNewPrivileges *bool - - // Rlimits specifies the resource limits, such as max open files, to set in the container - // If Rlimits are not set, the container will inherit rlimits from the parent process - Rlimits []configs.Rlimit - - // ConsoleSocket provides the masterfd console. - ConsoleSocket *os.File - - // Init specifies whether the process is the first process in the container. - Init bool - - ops processOperations - - LogLevel string - - // SubCgroupPaths specifies sub-cgroups to run the process in. - // Map keys are controller names, map values are paths (relative to - // container's top-level cgroup). - // - // If empty, the default top-level container's cgroup is used. - // - // For cgroup v2, the only key allowed is "". - SubCgroupPaths map[string]string -} - -// Wait waits for the process to exit. -// Wait releases any resources associated with the Process -func (p Process) Wait() (*os.ProcessState, error) { - if p.ops == nil { - return nil, errInvalidProcess - } - return p.ops.wait() -} - -// Pid returns the process ID -func (p Process) Pid() (int, error) { - // math.MinInt32 is returned here, because it's invalid value - // for the kill() system call. - if p.ops == nil { - return math.MinInt32, errInvalidProcess - } - return p.ops.pid(), nil -} - -// Signal sends a signal to the Process. -func (p Process) Signal(sig os.Signal) error { - if p.ops == nil { - return errInvalidProcess - } - return p.ops.signal(sig) -} - -// IO holds the process's STDIO -type IO struct { - Stdin io.WriteCloser - Stdout io.ReadCloser - Stderr io.ReadCloser -} diff --git a/vendor/github.com/opencontainers/runc/libcontainer/process_linux.go b/vendor/github.com/opencontainers/runc/libcontainer/process_linux.go deleted file mode 100644 index ac3b104ea02..00000000000 --- a/vendor/github.com/opencontainers/runc/libcontainer/process_linux.go +++ /dev/null @@ -1,823 +0,0 @@ -package libcontainer - -import ( - "encoding/json" - "errors" - "fmt" - "io" - "net" - "os" - "os/exec" - "path/filepath" - "strconv" - "time" - - "github.com/opencontainers/runc/libcontainer/cgroups" - "github.com/opencontainers/runc/libcontainer/cgroups/fs2" - "github.com/opencontainers/runc/libcontainer/configs" - "github.com/opencontainers/runc/libcontainer/intelrdt" - "github.com/opencontainers/runc/libcontainer/logs" - "github.com/opencontainers/runc/libcontainer/system" - "github.com/opencontainers/runc/libcontainer/utils" - "github.com/opencontainers/runtime-spec/specs-go" - "github.com/sirupsen/logrus" - "golang.org/x/sys/unix" -) - -type parentProcess interface { - // pid returns the pid for the running process. - pid() int - - // start starts the process execution. - start() error - - // send a SIGKILL to the process and wait for the exit. - terminate() error - - // wait waits on the process returning the process state. - wait() (*os.ProcessState, error) - - // startTime returns the process start time. - startTime() (uint64, error) - signal(os.Signal) error - externalDescriptors() []string - setExternalDescriptors(fds []string) - forwardChildLogs() chan error -} - -type filePair struct { - parent *os.File - child *os.File -} - -type setnsProcess struct { - cmd *exec.Cmd - messageSockPair filePair - logFilePair filePair - cgroupPaths map[string]string - rootlessCgroups bool - manager cgroups.Manager - intelRdtPath string - config *initConfig - fds []string - process *Process - bootstrapData io.Reader - initProcessPid int -} - -func (p *setnsProcess) startTime() (uint64, error) { - stat, err := system.Stat(p.pid()) - return stat.StartTime, err -} - -func (p *setnsProcess) signal(sig os.Signal) error { - s, ok := sig.(unix.Signal) - if !ok { - return errors.New("os: unsupported signal type") - } - return unix.Kill(p.pid(), s) -} - -func (p *setnsProcess) start() (retErr error) { - defer p.messageSockPair.parent.Close() - // get the "before" value of oom kill count - oom, _ := p.manager.OOMKillCount() - err := p.cmd.Start() - // close the write-side of the pipes (controlled by child) - p.messageSockPair.child.Close() - p.logFilePair.child.Close() - if err != nil { - return fmt.Errorf("error starting setns process: %w", err) - } - - waitInit := initWaiter(p.messageSockPair.parent) - defer func() { - if retErr != nil { - if newOom, err := p.manager.OOMKillCount(); err == nil && newOom != oom { - // Someone in this cgroup was killed, this _might_ be us. - retErr = fmt.Errorf("%w (possibly OOM-killed)", retErr) - } - werr := <-waitInit - if werr != nil { - logrus.WithError(werr).Warn() - } - err := ignoreTerminateErrors(p.terminate()) - if err != nil { - logrus.WithError(err).Warn("unable to terminate setnsProcess") - } - } - }() - - if p.bootstrapData != nil { - if _, err := io.Copy(p.messageSockPair.parent, p.bootstrapData); err != nil { - return fmt.Errorf("error copying bootstrap data to pipe: %w", err) - } - } - err = <-waitInit - if err != nil { - return err - } - if err := p.execSetns(); err != nil { - return fmt.Errorf("error executing setns process: %w", err) - } - for _, path := range p.cgroupPaths { - if err := cgroups.WriteCgroupProc(path, p.pid()); err != nil && !p.rootlessCgroups { - // On cgroup v2 + nesting + domain controllers, WriteCgroupProc may fail with EBUSY. - // https://github.com/opencontainers/runc/issues/2356#issuecomment-621277643 - // Try to join the cgroup of InitProcessPid. - if cgroups.IsCgroup2UnifiedMode() && p.initProcessPid != 0 { - initProcCgroupFile := fmt.Sprintf("/proc/%d/cgroup", p.initProcessPid) - initCg, initCgErr := cgroups.ParseCgroupFile(initProcCgroupFile) - if initCgErr == nil { - if initCgPath, ok := initCg[""]; ok { - initCgDirpath := filepath.Join(fs2.UnifiedMountpoint, initCgPath) - logrus.Debugf("adding pid %d to cgroups %v failed (%v), attempting to join %q (obtained from %s)", - p.pid(), p.cgroupPaths, err, initCg, initCgDirpath) - // NOTE: initCgDirPath is not guaranteed to exist because we didn't pause the container. - err = cgroups.WriteCgroupProc(initCgDirpath, p.pid()) - } - } - } - if err != nil { - return fmt.Errorf("error adding pid %d to cgroups: %w", p.pid(), err) - } - } - } - if p.intelRdtPath != "" { - // if Intel RDT "resource control" filesystem path exists - _, err := os.Stat(p.intelRdtPath) - if err == nil { - if err := intelrdt.WriteIntelRdtTasks(p.intelRdtPath, p.pid()); err != nil { - return fmt.Errorf("error adding pid %d to Intel RDT: %w", p.pid(), err) - } - } - } - - if err := utils.WriteJSON(p.messageSockPair.parent, p.config); err != nil { - return fmt.Errorf("error writing config to pipe: %w", err) - } - - ierr := parseSync(p.messageSockPair.parent, func(sync *syncT) error { - switch sync.Type { - case procReady: - // Set rlimits, this has to be done here because we lose permissions - // to raise the limits once we enter a user-namespace - if err := setupRlimits(p.config.Rlimits, p.pid()); err != nil { - return fmt.Errorf("error setting rlimits for ready process: %w", err) - } - - // Sync with child. - return writeSync(p.messageSockPair.parent, procRun) - case procHooks: - // This shouldn't happen. - panic("unexpected procHooks in setns") - case procSeccomp: - if p.config.Config.Seccomp.ListenerPath == "" { - return errors.New("listenerPath is not set") - } - - seccompFd, err := recvSeccompFd(uintptr(p.pid()), uintptr(sync.Fd)) - if err != nil { - return err - } - defer unix.Close(seccompFd) - - bundle, annotations := utils.Annotations(p.config.Config.Labels) - containerProcessState := &specs.ContainerProcessState{ - Version: specs.Version, - Fds: []string{specs.SeccompFdName}, - Pid: p.cmd.Process.Pid, - Metadata: p.config.Config.Seccomp.ListenerMetadata, - State: specs.State{ - Version: specs.Version, - ID: p.config.ContainerId, - Status: specs.StateRunning, - Pid: p.initProcessPid, - Bundle: bundle, - Annotations: annotations, - }, - } - if err := sendContainerProcessState(p.config.Config.Seccomp.ListenerPath, - containerProcessState, seccompFd); err != nil { - return err - } - - // Sync with child. - if err := writeSync(p.messageSockPair.parent, procSeccompDone); err != nil { - return err - } - return nil - default: - return errors.New("invalid JSON payload from child") - } - }) - - if err := unix.Shutdown(int(p.messageSockPair.parent.Fd()), unix.SHUT_WR); err != nil { - return &os.PathError{Op: "shutdown", Path: "(init pipe)", Err: err} - } - // Must be done after Shutdown so the child will exit and we can wait for it. - if ierr != nil { - _, _ = p.wait() - return ierr - } - return nil -} - -// execSetns runs the process that executes C code to perform the setns calls -// because setns support requires the C process to fork off a child and perform the setns -// before the go runtime boots, we wait on the process to die and receive the child's pid -// over the provided pipe. -func (p *setnsProcess) execSetns() error { - status, err := p.cmd.Process.Wait() - if err != nil { - _ = p.cmd.Wait() - return fmt.Errorf("error waiting on setns process to finish: %w", err) - } - if !status.Success() { - _ = p.cmd.Wait() - return &exec.ExitError{ProcessState: status} - } - var pid *pid - if err := json.NewDecoder(p.messageSockPair.parent).Decode(&pid); err != nil { - _ = p.cmd.Wait() - return fmt.Errorf("error reading pid from init pipe: %w", err) - } - - // Clean up the zombie parent process - // On Unix systems FindProcess always succeeds. - firstChildProcess, _ := os.FindProcess(pid.PidFirstChild) - - // Ignore the error in case the child has already been reaped for any reason - _, _ = firstChildProcess.Wait() - - process, err := os.FindProcess(pid.Pid) - if err != nil { - return err - } - p.cmd.Process = process - p.process.ops = p - return nil -} - -// terminate sends a SIGKILL to the forked process for the setns routine then waits to -// avoid the process becoming a zombie. -func (p *setnsProcess) terminate() error { - if p.cmd.Process == nil { - return nil - } - err := p.cmd.Process.Kill() - if _, werr := p.wait(); err == nil { - err = werr - } - return err -} - -func (p *setnsProcess) wait() (*os.ProcessState, error) { - err := p.cmd.Wait() - - // Return actual ProcessState even on Wait error - return p.cmd.ProcessState, err -} - -func (p *setnsProcess) pid() int { - return p.cmd.Process.Pid -} - -func (p *setnsProcess) externalDescriptors() []string { - return p.fds -} - -func (p *setnsProcess) setExternalDescriptors(newFds []string) { - p.fds = newFds -} - -func (p *setnsProcess) forwardChildLogs() chan error { - return logs.ForwardLogs(p.logFilePair.parent) -} - -type initProcess struct { - cmd *exec.Cmd - messageSockPair filePair - logFilePair filePair - config *initConfig - manager cgroups.Manager - intelRdtManager *intelrdt.Manager - container *linuxContainer - fds []string - process *Process - bootstrapData io.Reader - sharePidns bool -} - -func (p *initProcess) pid() int { - return p.cmd.Process.Pid -} - -func (p *initProcess) externalDescriptors() []string { - return p.fds -} - -// getChildPid receives the final child's pid over the provided pipe. -func (p *initProcess) getChildPid() (int, error) { - var pid pid - if err := json.NewDecoder(p.messageSockPair.parent).Decode(&pid); err != nil { - _ = p.cmd.Wait() - return -1, err - } - - // Clean up the zombie parent process - // On Unix systems FindProcess always succeeds. - firstChildProcess, _ := os.FindProcess(pid.PidFirstChild) - - // Ignore the error in case the child has already been reaped for any reason - _, _ = firstChildProcess.Wait() - - return pid.Pid, nil -} - -func (p *initProcess) waitForChildExit(childPid int) error { - status, err := p.cmd.Process.Wait() - if err != nil { - _ = p.cmd.Wait() - return err - } - if !status.Success() { - _ = p.cmd.Wait() - return &exec.ExitError{ProcessState: status} - } - - process, err := os.FindProcess(childPid) - if err != nil { - return err - } - p.cmd.Process = process - p.process.ops = p - return nil -} - -func (p *initProcess) start() (retErr error) { - defer p.messageSockPair.parent.Close() //nolint: errcheck - err := p.cmd.Start() - p.process.ops = p - // close the write-side of the pipes (controlled by child) - _ = p.messageSockPair.child.Close() - _ = p.logFilePair.child.Close() - if err != nil { - p.process.ops = nil - return fmt.Errorf("unable to start init: %w", err) - } - - waitInit := initWaiter(p.messageSockPair.parent) - defer func() { - if retErr != nil { - // Find out if init is killed by the kernel's OOM killer. - // Get the count before killing init as otherwise cgroup - // might be removed by systemd. - oom, err := p.manager.OOMKillCount() - if err != nil { - logrus.WithError(err).Warn("unable to get oom kill count") - } else if oom > 0 { - // Does not matter what the particular error was, - // its cause is most probably OOM, so report that. - const oomError = "container init was OOM-killed (memory limit too low?)" - - if logrus.GetLevel() >= logrus.DebugLevel { - // Only show the original error if debug is set, - // as it is not generally very useful. - retErr = fmt.Errorf(oomError+": %w", retErr) - } else { - retErr = errors.New(oomError) - } - } - - werr := <-waitInit - if werr != nil { - logrus.WithError(werr).Warn() - } - - // Terminate the process to ensure we can remove cgroups. - if err := ignoreTerminateErrors(p.terminate()); err != nil { - logrus.WithError(err).Warn("unable to terminate initProcess") - } - - _ = p.manager.Destroy() - if p.intelRdtManager != nil { - _ = p.intelRdtManager.Destroy() - } - } - }() - - // Do this before syncing with child so that no children can escape the - // cgroup. We don't need to worry about not doing this and not being root - // because we'd be using the rootless cgroup manager in that case. - if err := p.manager.Apply(p.pid()); err != nil { - return fmt.Errorf("unable to apply cgroup configuration: %w", err) - } - if p.intelRdtManager != nil { - if err := p.intelRdtManager.Apply(p.pid()); err != nil { - return fmt.Errorf("unable to apply Intel RDT configuration: %w", err) - } - } - if _, err := io.Copy(p.messageSockPair.parent, p.bootstrapData); err != nil { - return fmt.Errorf("can't copy bootstrap data to pipe: %w", err) - } - err = <-waitInit - if err != nil { - return err - } - - childPid, err := p.getChildPid() - if err != nil { - return fmt.Errorf("can't get final child's PID from pipe: %w", err) - } - - // Save the standard descriptor names before the container process - // can potentially move them (e.g., via dup2()). If we don't do this now, - // we won't know at checkpoint time which file descriptor to look up. - fds, err := getPipeFds(childPid) - if err != nil { - return fmt.Errorf("error getting pipe fds for pid %d: %w", childPid, err) - } - p.setExternalDescriptors(fds) - - // Wait for our first child to exit - if err := p.waitForChildExit(childPid); err != nil { - return fmt.Errorf("error waiting for our first child to exit: %w", err) - } - - if err := p.createNetworkInterfaces(); err != nil { - return fmt.Errorf("error creating network interfaces: %w", err) - } - if err := p.updateSpecState(); err != nil { - return fmt.Errorf("error updating spec state: %w", err) - } - if err := p.sendConfig(); err != nil { - return fmt.Errorf("error sending config to init process: %w", err) - } - var ( - sentRun bool - sentResume bool - ) - - ierr := parseSync(p.messageSockPair.parent, func(sync *syncT) error { - switch sync.Type { - case procSeccomp: - if p.config.Config.Seccomp.ListenerPath == "" { - return errors.New("listenerPath is not set") - } - - seccompFd, err := recvSeccompFd(uintptr(childPid), uintptr(sync.Fd)) - if err != nil { - return err - } - defer unix.Close(seccompFd) - - s, err := p.container.currentOCIState() - if err != nil { - return err - } - - // initProcessStartTime hasn't been set yet. - s.Pid = p.cmd.Process.Pid - s.Status = specs.StateCreating - containerProcessState := &specs.ContainerProcessState{ - Version: specs.Version, - Fds: []string{specs.SeccompFdName}, - Pid: s.Pid, - Metadata: p.config.Config.Seccomp.ListenerMetadata, - State: *s, - } - if err := sendContainerProcessState(p.config.Config.Seccomp.ListenerPath, - containerProcessState, seccompFd); err != nil { - return err - } - - // Sync with child. - if err := writeSync(p.messageSockPair.parent, procSeccompDone); err != nil { - return err - } - case procReady: - // Set rlimits, this has to be done here because we lose permissions - // to raise the limits once we enter a user-namespace - if err := setupRlimits(p.config.Rlimits, p.pid()); err != nil { - return fmt.Errorf("error setting rlimits for ready process: %w", err) - } - // call prestart and CreateRuntime hooks - if !p.config.Config.Namespaces.Contains(configs.NEWNS) { - // Setup cgroup before the hook, so that the prestart and CreateRuntime hook could apply cgroup permissions. - if err := p.manager.Set(p.config.Config.Cgroups.Resources); err != nil { - return fmt.Errorf("error setting cgroup config for ready process: %w", err) - } - if p.intelRdtManager != nil { - if err := p.intelRdtManager.Set(p.config.Config); err != nil { - return fmt.Errorf("error setting Intel RDT config for ready process: %w", err) - } - } - - if len(p.config.Config.Hooks) != 0 { - s, err := p.container.currentOCIState() - if err != nil { - return err - } - // initProcessStartTime hasn't been set yet. - s.Pid = p.cmd.Process.Pid - s.Status = specs.StateCreating - hooks := p.config.Config.Hooks - - if err := hooks[configs.Prestart].RunHooks(s); err != nil { - return err - } - if err := hooks[configs.CreateRuntime].RunHooks(s); err != nil { - return err - } - } - } - - // generate a timestamp indicating when the container was started - p.container.created = time.Now().UTC() - p.container.state = &createdState{ - c: p.container, - } - - // NOTE: If the procRun state has been synced and the - // runc-create process has been killed for some reason, - // the runc-init[2:stage] process will be leaky. And - // the runc command also fails to parse root directory - // because the container doesn't have state.json. - // - // In order to cleanup the runc-init[2:stage] by - // runc-delete/stop, we should store the status before - // procRun sync. - state, uerr := p.container.updateState(p) - if uerr != nil { - return fmt.Errorf("unable to store init state: %w", err) - } - p.container.initProcessStartTime = state.InitProcessStartTime - - // Sync with child. - if err := writeSync(p.messageSockPair.parent, procRun); err != nil { - return err - } - sentRun = true - case procHooks: - // Setup cgroup before prestart hook, so that the prestart hook could apply cgroup permissions. - if err := p.manager.Set(p.config.Config.Cgroups.Resources); err != nil { - return fmt.Errorf("error setting cgroup config for procHooks process: %w", err) - } - if p.intelRdtManager != nil { - if err := p.intelRdtManager.Set(p.config.Config); err != nil { - return fmt.Errorf("error setting Intel RDT config for procHooks process: %w", err) - } - } - if len(p.config.Config.Hooks) != 0 { - s, err := p.container.currentOCIState() - if err != nil { - return err - } - // initProcessStartTime hasn't been set yet. - s.Pid = p.cmd.Process.Pid - s.Status = specs.StateCreating - hooks := p.config.Config.Hooks - - if err := hooks[configs.Prestart].RunHooks(s); err != nil { - return err - } - if err := hooks[configs.CreateRuntime].RunHooks(s); err != nil { - return err - } - } - // Sync with child. - if err := writeSync(p.messageSockPair.parent, procResume); err != nil { - return err - } - sentResume = true - default: - return errors.New("invalid JSON payload from child") - } - - return nil - }) - - if !sentRun { - return fmt.Errorf("error during container init: %w", ierr) - } - if p.config.Config.Namespaces.Contains(configs.NEWNS) && !sentResume { - return errors.New("could not synchronise after executing prestart and CreateRuntime hooks with container process") - } - if err := unix.Shutdown(int(p.messageSockPair.parent.Fd()), unix.SHUT_WR); err != nil { - return &os.PathError{Op: "shutdown", Path: "(init pipe)", Err: err} - } - - // Must be done after Shutdown so the child will exit and we can wait for it. - if ierr != nil { - _, _ = p.wait() - return ierr - } - return nil -} - -func (p *initProcess) wait() (*os.ProcessState, error) { - err := p.cmd.Wait() - // we should kill all processes in cgroup when init is died if we use host PID namespace - if p.sharePidns { - _ = signalAllProcesses(p.manager, unix.SIGKILL) - } - return p.cmd.ProcessState, err -} - -func (p *initProcess) terminate() error { - if p.cmd.Process == nil { - return nil - } - err := p.cmd.Process.Kill() - if _, werr := p.wait(); err == nil { - err = werr - } - return err -} - -func (p *initProcess) startTime() (uint64, error) { - stat, err := system.Stat(p.pid()) - return stat.StartTime, err -} - -func (p *initProcess) updateSpecState() error { - s, err := p.container.currentOCIState() - if err != nil { - return err - } - - p.config.SpecState = s - return nil -} - -func (p *initProcess) sendConfig() error { - // send the config to the container's init process, we don't use JSON Encode - // here because there might be a problem in JSON decoder in some cases, see: - // https://github.com/docker/docker/issues/14203#issuecomment-174177790 - return utils.WriteJSON(p.messageSockPair.parent, p.config) -} - -func (p *initProcess) createNetworkInterfaces() error { - for _, config := range p.config.Config.Networks { - strategy, err := getStrategy(config.Type) - if err != nil { - return err - } - n := &network{ - Network: *config, - } - if err := strategy.create(n, p.pid()); err != nil { - return err - } - p.config.Networks = append(p.config.Networks, n) - } - return nil -} - -func (p *initProcess) signal(sig os.Signal) error { - s, ok := sig.(unix.Signal) - if !ok { - return errors.New("os: unsupported signal type") - } - return unix.Kill(p.pid(), s) -} - -func (p *initProcess) setExternalDescriptors(newFds []string) { - p.fds = newFds -} - -func (p *initProcess) forwardChildLogs() chan error { - return logs.ForwardLogs(p.logFilePair.parent) -} - -func recvSeccompFd(childPid, childFd uintptr) (int, error) { - pidfd, _, errno := unix.Syscall(unix.SYS_PIDFD_OPEN, childPid, 0, 0) - if errno != 0 { - return -1, fmt.Errorf("performing SYS_PIDFD_OPEN syscall: %w", errno) - } - defer unix.Close(int(pidfd)) - - seccompFd, _, errno := unix.Syscall(unix.SYS_PIDFD_GETFD, pidfd, childFd, 0) - if errno != 0 { - return -1, fmt.Errorf("performing SYS_PIDFD_GETFD syscall: %w", errno) - } - - return int(seccompFd), nil -} - -func sendContainerProcessState(listenerPath string, state *specs.ContainerProcessState, fd int) error { - conn, err := net.Dial("unix", listenerPath) - if err != nil { - return fmt.Errorf("failed to connect with seccomp agent specified in the seccomp profile: %w", err) - } - - socket, err := conn.(*net.UnixConn).File() - if err != nil { - return fmt.Errorf("cannot get seccomp socket: %w", err) - } - defer socket.Close() - - b, err := json.Marshal(state) - if err != nil { - return fmt.Errorf("cannot marshall seccomp state: %w", err) - } - - err = utils.SendFds(socket, b, fd) - if err != nil { - return fmt.Errorf("cannot send seccomp fd to %s: %w", listenerPath, err) - } - - return nil -} - -func getPipeFds(pid int) ([]string, error) { - fds := make([]string, 3) - - dirPath := filepath.Join("/proc", strconv.Itoa(pid), "/fd") - for i := 0; i < 3; i++ { - // XXX: This breaks if the path is not a valid symlink (which can - // happen in certain particularly unlucky mount namespace setups). - f := filepath.Join(dirPath, strconv.Itoa(i)) - target, err := os.Readlink(f) - if err != nil { - // Ignore permission errors, for rootless containers and other - // non-dumpable processes. if we can't get the fd for a particular - // file, there's not much we can do. - if os.IsPermission(err) { - continue - } - return fds, err - } - fds[i] = target - } - return fds, nil -} - -// InitializeIO creates pipes for use with the process's stdio and returns the -// opposite side for each. Do not use this if you want to have a pseudoterminal -// set up for you by libcontainer (TODO: fix that too). -// TODO: This is mostly unnecessary, and should be handled by clients. -func (p *Process) InitializeIO(rootuid, rootgid int) (i *IO, err error) { - var fds []uintptr - i = &IO{} - // cleanup in case of an error - defer func() { - if err != nil { - for _, fd := range fds { - _ = unix.Close(int(fd)) - } - } - }() - // STDIN - r, w, err := os.Pipe() - if err != nil { - return nil, err - } - fds = append(fds, r.Fd(), w.Fd()) - p.Stdin, i.Stdin = r, w - // STDOUT - if r, w, err = os.Pipe(); err != nil { - return nil, err - } - fds = append(fds, r.Fd(), w.Fd()) - p.Stdout, i.Stdout = w, r - // STDERR - if r, w, err = os.Pipe(); err != nil { - return nil, err - } - fds = append(fds, r.Fd(), w.Fd()) - p.Stderr, i.Stderr = w, r - // change ownership of the pipes in case we are in a user namespace - for _, fd := range fds { - if err := unix.Fchown(int(fd), rootuid, rootgid); err != nil { - return nil, &os.PathError{Op: "fchown", Path: "fd " + strconv.Itoa(int(fd)), Err: err} - } - } - return i, nil -} - -// initWaiter returns a channel to wait on for making sure -// runc init has finished the initial setup. -func initWaiter(r io.Reader) chan error { - ch := make(chan error, 1) - go func() { - defer close(ch) - - inited := make([]byte, 1) - n, err := r.Read(inited) - if err == nil { - if n < 1 { - err = errors.New("short read") - } else if inited[0] != 0 { - err = fmt.Errorf("unexpected %d != 0", inited[0]) - } else { - ch <- nil - return - } - } - ch <- fmt.Errorf("waiting for init preliminary setup: %w", err) - }() - - return ch -} diff --git a/vendor/github.com/opencontainers/runc/libcontainer/restored_process.go b/vendor/github.com/opencontainers/runc/libcontainer/restored_process.go deleted file mode 100644 index cdffbd3aff5..00000000000 --- a/vendor/github.com/opencontainers/runc/libcontainer/restored_process.go +++ /dev/null @@ -1,128 +0,0 @@ -package libcontainer - -import ( - "errors" - "os" - "os/exec" - - "github.com/opencontainers/runc/libcontainer/system" -) - -func newRestoredProcess(cmd *exec.Cmd, fds []string) (*restoredProcess, error) { - var err error - pid := cmd.Process.Pid - stat, err := system.Stat(pid) - if err != nil { - return nil, err - } - return &restoredProcess{ - cmd: cmd, - processStartTime: stat.StartTime, - fds: fds, - }, nil -} - -type restoredProcess struct { - cmd *exec.Cmd - processStartTime uint64 - fds []string -} - -func (p *restoredProcess) start() error { - return errors.New("restored process cannot be started") -} - -func (p *restoredProcess) pid() int { - return p.cmd.Process.Pid -} - -func (p *restoredProcess) terminate() error { - err := p.cmd.Process.Kill() - if _, werr := p.wait(); err == nil { - err = werr - } - return err -} - -func (p *restoredProcess) wait() (*os.ProcessState, error) { - // TODO: how do we wait on the actual process? - // maybe use --exec-cmd in criu - err := p.cmd.Wait() - if err != nil { - var exitErr *exec.ExitError - if !errors.As(err, &exitErr) { - return nil, err - } - } - st := p.cmd.ProcessState - return st, nil -} - -func (p *restoredProcess) startTime() (uint64, error) { - return p.processStartTime, nil -} - -func (p *restoredProcess) signal(s os.Signal) error { - return p.cmd.Process.Signal(s) -} - -func (p *restoredProcess) externalDescriptors() []string { - return p.fds -} - -func (p *restoredProcess) setExternalDescriptors(newFds []string) { - p.fds = newFds -} - -func (p *restoredProcess) forwardChildLogs() chan error { - return nil -} - -// nonChildProcess represents a process where the calling process is not -// the parent process. This process is created when a factory loads a container from -// a persisted state. -type nonChildProcess struct { - processPid int - processStartTime uint64 - fds []string -} - -func (p *nonChildProcess) start() error { - return errors.New("restored process cannot be started") -} - -func (p *nonChildProcess) pid() int { - return p.processPid -} - -func (p *nonChildProcess) terminate() error { - return errors.New("restored process cannot be terminated") -} - -func (p *nonChildProcess) wait() (*os.ProcessState, error) { - return nil, errors.New("restored process cannot be waited on") -} - -func (p *nonChildProcess) startTime() (uint64, error) { - return p.processStartTime, nil -} - -func (p *nonChildProcess) signal(s os.Signal) error { - proc, err := os.FindProcess(p.processPid) - if err != nil { - return err - } - return proc.Signal(s) -} - -func (p *nonChildProcess) externalDescriptors() []string { - return p.fds -} - -func (p *nonChildProcess) setExternalDescriptors(newFds []string) { - p.fds = newFds -} - -func (p *nonChildProcess) forwardChildLogs() chan error { - return nil -} diff --git a/vendor/github.com/opencontainers/runc/libcontainer/rootfs_linux.go b/vendor/github.com/opencontainers/runc/libcontainer/rootfs_linux.go deleted file mode 100644 index 04ec6d7e474..00000000000 --- a/vendor/github.com/opencontainers/runc/libcontainer/rootfs_linux.go +++ /dev/null @@ -1,1155 +0,0 @@ -package libcontainer - -import ( - "errors" - "fmt" - "io" - "os" - "os/exec" - "path" - "path/filepath" - "strconv" - "strings" - "time" - - securejoin "github.com/cyphar/filepath-securejoin" - "github.com/moby/sys/mountinfo" - "github.com/mrunalp/fileutils" - "github.com/opencontainers/runc/libcontainer/cgroups" - "github.com/opencontainers/runc/libcontainer/cgroups/fs2" - "github.com/opencontainers/runc/libcontainer/configs" - "github.com/opencontainers/runc/libcontainer/devices" - "github.com/opencontainers/runc/libcontainer/userns" - "github.com/opencontainers/runc/libcontainer/utils" - "github.com/opencontainers/runtime-spec/specs-go" - "github.com/opencontainers/selinux/go-selinux/label" - "github.com/sirupsen/logrus" - "golang.org/x/sys/unix" -) - -const defaultMountFlags = unix.MS_NOEXEC | unix.MS_NOSUID | unix.MS_NODEV - -type mountConfig struct { - root string - label string - cgroup2Path string - rootlessCgroups bool - cgroupns bool - fd *int -} - -// needsSetupDev returns true if /dev needs to be set up. -func needsSetupDev(config *configs.Config) bool { - for _, m := range config.Mounts { - if m.Device == "bind" && utils.CleanPath(m.Destination) == "/dev" { - return false - } - } - return true -} - -// prepareRootfs sets up the devices, mount points, and filesystems for use -// inside a new mount namespace. It doesn't set anything as ro. You must call -// finalizeRootfs after this function to finish setting up the rootfs. -func prepareRootfs(pipe io.ReadWriter, iConfig *initConfig, mountFds []int) (err error) { - config := iConfig.Config - if err := prepareRoot(config); err != nil { - return fmt.Errorf("error preparing rootfs: %w", err) - } - - if mountFds != nil && len(mountFds) != len(config.Mounts) { - return fmt.Errorf("malformed mountFds slice. Expected size: %v, got: %v. Slice: %v", len(config.Mounts), len(mountFds), mountFds) - } - - mountConfig := &mountConfig{ - root: config.Rootfs, - label: config.MountLabel, - cgroup2Path: iConfig.Cgroup2Path, - rootlessCgroups: iConfig.RootlessCgroups, - cgroupns: config.Namespaces.Contains(configs.NEWCGROUP), - } - setupDev := needsSetupDev(config) - for i, m := range config.Mounts { - for _, precmd := range m.PremountCmds { - if err := mountCmd(precmd); err != nil { - return fmt.Errorf("error running premount command: %w", err) - } - } - - // Just before the loop we checked that if not empty, len(mountFds) == len(config.Mounts). - // Therefore, we can access mountFds[i] without any concerns. - if mountFds != nil && mountFds[i] != -1 { - mountConfig.fd = &mountFds[i] - } else { - mountConfig.fd = nil - } - - if err := mountToRootfs(m, mountConfig); err != nil { - return fmt.Errorf("error mounting %q to rootfs at %q: %w", m.Source, m.Destination, err) - } - - for _, postcmd := range m.PostmountCmds { - if err := mountCmd(postcmd); err != nil { - return fmt.Errorf("error running postmount command: %w", err) - } - } - } - - if setupDev { - if err := createDevices(config); err != nil { - return fmt.Errorf("error creating device nodes: %w", err) - } - if err := setupPtmx(config); err != nil { - return fmt.Errorf("error setting up ptmx: %w", err) - } - if err := setupDevSymlinks(config.Rootfs); err != nil { - return fmt.Errorf("error setting up /dev symlinks: %w", err) - } - } - - // Signal the parent to run the pre-start hooks. - // The hooks are run after the mounts are setup, but before we switch to the new - // root, so that the old root is still available in the hooks for any mount - // manipulations. - // Note that iConfig.Cwd is not guaranteed to exist here. - if err := syncParentHooks(pipe); err != nil { - return err - } - - // The reason these operations are done here rather than in finalizeRootfs - // is because the console-handling code gets quite sticky if we have to set - // up the console before doing the pivot_root(2). This is because the - // Console API has to also work with the ExecIn case, which means that the - // API must be able to deal with being inside as well as outside the - // container. It's just cleaner to do this here (at the expense of the - // operation not being perfectly split). - - if err := unix.Chdir(config.Rootfs); err != nil { - return &os.PathError{Op: "chdir", Path: config.Rootfs, Err: err} - } - - s := iConfig.SpecState - s.Pid = unix.Getpid() - s.Status = specs.StateCreating - if err := iConfig.Config.Hooks[configs.CreateContainer].RunHooks(s); err != nil { - return err - } - - if config.NoPivotRoot { - err = msMoveRoot(config.Rootfs) - } else if config.Namespaces.Contains(configs.NEWNS) { - err = pivotRoot(config.Rootfs) - } else { - err = chroot() - } - if err != nil { - return fmt.Errorf("error jailing process inside rootfs: %w", err) - } - - if setupDev { - if err := reOpenDevNull(); err != nil { - return fmt.Errorf("error reopening /dev/null inside container: %w", err) - } - } - - if cwd := iConfig.Cwd; cwd != "" { - // Note that spec.Process.Cwd can contain unclean value like "../../../../foo/bar...". - // However, we are safe to call MkDirAll directly because we are in the jail here. - if err := os.MkdirAll(cwd, 0o755); err != nil { - return err - } - } - - return nil -} - -// finalizeRootfs sets anything to ro if necessary. You must call -// prepareRootfs first. -func finalizeRootfs(config *configs.Config) (err error) { - // All tmpfs mounts and /dev were previously mounted as rw - // by mountPropagate. Remount them read-only as requested. - for _, m := range config.Mounts { - if m.Flags&unix.MS_RDONLY != unix.MS_RDONLY { - continue - } - if m.Device == "tmpfs" || utils.CleanPath(m.Destination) == "/dev" { - if err := remountReadonly(m); err != nil { - return err - } - } - } - - // set rootfs ( / ) as readonly - if config.Readonlyfs { - if err := setReadonly(); err != nil { - return fmt.Errorf("error setting rootfs as readonly: %w", err) - } - } - - if config.Umask != nil { - unix.Umask(int(*config.Umask)) - } else { - unix.Umask(0o022) - } - return nil -} - -// /tmp has to be mounted as private to allow MS_MOVE to work in all situations -func prepareTmp(topTmpDir string) (string, error) { - tmpdir, err := os.MkdirTemp(topTmpDir, "runctop") - if err != nil { - return "", err - } - if err := mount(tmpdir, tmpdir, "", "bind", unix.MS_BIND, ""); err != nil { - return "", err - } - if err := mount("", tmpdir, "", "", uintptr(unix.MS_PRIVATE), ""); err != nil { - return "", err - } - return tmpdir, nil -} - -func cleanupTmp(tmpdir string) { - _ = unix.Unmount(tmpdir, 0) - _ = os.RemoveAll(tmpdir) -} - -func mountCmd(cmd configs.Command) error { - command := exec.Command(cmd.Path, cmd.Args[:]...) - command.Env = cmd.Env - command.Dir = cmd.Dir - if out, err := command.CombinedOutput(); err != nil { - return fmt.Errorf("%#v failed: %s: %w", cmd, string(out), err) - } - return nil -} - -func mountCgroupV1(m *configs.Mount, c *mountConfig) error { - binds, err := getCgroupMounts(m) - if err != nil { - return err - } - var merged []string - for _, b := range binds { - ss := filepath.Base(b.Destination) - if strings.Contains(ss, ",") { - merged = append(merged, ss) - } - } - tmpfs := &configs.Mount{ - Source: "tmpfs", - Device: "tmpfs", - Destination: m.Destination, - Flags: defaultMountFlags, - Data: "mode=755", - PropagationFlags: m.PropagationFlags, - } - - if err := mountToRootfs(tmpfs, c); err != nil { - return err - } - - for _, b := range binds { - if c.cgroupns { - subsystemPath := filepath.Join(c.root, b.Destination) - subsystemName := filepath.Base(b.Destination) - if err := utils.MkdirAllInRoot(c.root, subsystemPath, 0o755); err != nil { - return err - } - if err := utils.WithProcfd(c.root, b.Destination, func(procfd string) error { - flags := defaultMountFlags - if m.Flags&unix.MS_RDONLY != 0 { - flags = flags | unix.MS_RDONLY - } - var ( - source = "cgroup" - data = subsystemName - ) - if data == "systemd" { - data = cgroups.CgroupNamePrefix + data - source = "systemd" - } - return mount(source, b.Destination, procfd, "cgroup", uintptr(flags), data) - }); err != nil { - return err - } - } else { - if err := mountToRootfs(b, c); err != nil { - return err - } - } - } - for _, mc := range merged { - for _, ss := range strings.Split(mc, ",") { - // symlink(2) is very dumb, it will just shove the path into - // the link and doesn't do any checks or relative path - // conversion. Also, don't error out if the cgroup already exists. - if err := os.Symlink(mc, filepath.Join(c.root, m.Destination, ss)); err != nil && !os.IsExist(err) { - return err - } - } - } - return nil -} - -func mountCgroupV2(m *configs.Mount, c *mountConfig) error { - err := utils.WithProcfd(c.root, m.Destination, func(procfd string) error { - return mount(m.Source, m.Destination, procfd, "cgroup2", uintptr(m.Flags), m.Data) - }) - if err == nil || !(errors.Is(err, unix.EPERM) || errors.Is(err, unix.EBUSY)) { - return err - } - - // When we are in UserNS but CgroupNS is not unshared, we cannot mount - // cgroup2 (#2158), so fall back to bind mount. - bindM := &configs.Mount{ - Device: "bind", - Source: fs2.UnifiedMountpoint, - Destination: m.Destination, - Flags: unix.MS_BIND | m.Flags, - PropagationFlags: m.PropagationFlags, - } - if c.cgroupns && c.cgroup2Path != "" { - // Emulate cgroupns by bind-mounting the container cgroup path - // rather than the whole /sys/fs/cgroup. - bindM.Source = c.cgroup2Path - } - // mountToRootfs() handles remounting for MS_RDONLY. - // No need to set c.fd here, because mountToRootfs() calls utils.WithProcfd() by itself in mountPropagate(). - err = mountToRootfs(bindM, c) - if c.rootlessCgroups && errors.Is(err, unix.ENOENT) { - // ENOENT (for `src = c.cgroup2Path`) happens when rootless runc is being executed - // outside the userns+mountns. - // - // Mask `/sys/fs/cgroup` to ensure it is read-only, even when `/sys` is mounted - // with `rbind,ro` (`runc spec --rootless` produces `rbind,ro` for `/sys`). - err = utils.WithProcfd(c.root, m.Destination, func(procfd string) error { - return maskPath(procfd, c.label) - }) - } - return err -} - -func doTmpfsCopyUp(m *configs.Mount, rootfs, mountLabel string) (Err error) { - // Set up a scratch dir for the tmpfs on the host. - tmpdir, err := prepareTmp("/tmp") - if err != nil { - return fmt.Errorf("tmpcopyup: failed to setup tmpdir: %w", err) - } - defer cleanupTmp(tmpdir) - tmpDir, err := os.MkdirTemp(tmpdir, "runctmpdir") - if err != nil { - return fmt.Errorf("tmpcopyup: failed to create tmpdir: %w", err) - } - defer os.RemoveAll(tmpDir) - - // Configure the *host* tmpdir as if it's the container mount. We change - // m.Destination since we are going to mount *on the host*. - oldDest := m.Destination - m.Destination = tmpDir - err = mountPropagate(m, "/", mountLabel, nil) - m.Destination = oldDest - if err != nil { - return err - } - defer func() { - if Err != nil { - if err := unmount(tmpDir, unix.MNT_DETACH); err != nil { - logrus.Warnf("tmpcopyup: %v", err) - } - } - }() - - return utils.WithProcfd(rootfs, m.Destination, func(procfd string) (Err error) { - // Copy the container data to the host tmpdir. We append "/" to force - // CopyDirectory to resolve the symlink rather than trying to copy the - // symlink itself. - if err := fileutils.CopyDirectory(procfd+"/", tmpDir); err != nil { - return fmt.Errorf("tmpcopyup: failed to copy %s to %s (%s): %w", m.Destination, procfd, tmpDir, err) - } - // Now move the mount into the container. - if err := mount(tmpDir, m.Destination, procfd, "", unix.MS_MOVE, ""); err != nil { - return fmt.Errorf("tmpcopyup: failed to move mount: %w", err) - } - return nil - }) -} - -var errRootfsToFile = errors.New("config tries to change rootfs to file") - -func createMountpoint(rootfs string, m *configs.Mount, mountFd *int, source string) (string, error) { - dest, err := securejoin.SecureJoin(rootfs, m.Destination) - if err != nil { - return "", err - } - if err := checkProcMount(rootfs, dest, m, source); err != nil { - return "", fmt.Errorf("check proc-safety of %s mount: %w", m.Destination, err) - } - - switch m.Device { - case "bind": - source := m.Source - if mountFd != nil { - source = "/proc/self/fd/" + strconv.Itoa(*mountFd) - } - - fi, err := os.Stat(source) - if err != nil { - // Error out if the source of a bind mount does not exist as we - // will be unable to bind anything to it. - return "", fmt.Errorf("bind mount source stat: %w", err) - } - // If the original source is not a directory, make the target a file. - if !fi.IsDir() { - // Make sure we aren't tricked into trying to make the root a file. - if rootfs == dest { - return "", fmt.Errorf("%w: file bind mount over rootfs", errRootfsToFile) - } - // Make the parent directory. - destDir, destBase := filepath.Split(dest) - destDirFd, err := utils.MkdirAllInRootOpen(rootfs, destDir, 0o755) - if err != nil { - return "", fmt.Errorf("make parent dir of file bind-mount: %w", err) - } - defer destDirFd.Close() - // Make the target file. We want to avoid opening any file that is - // already there because it could be a "bad" file like an invalid - // device or hung tty that might cause a DoS, so we use mknodat. - // destBase does not contain any "/" components, and mknodat does - // not follow trailing symlinks, so we can safely just call mknodat - // here. - if err := unix.Mknodat(int(destDirFd.Fd()), destBase, unix.S_IFREG|0o644, 0); err != nil { - // If we get EEXIST, there was already an inode there and - // we can consider that a success. - if !errors.Is(err, unix.EEXIST) { - err = &os.PathError{Op: "mknod regular file", Path: dest, Err: err} - return "", fmt.Errorf("create target of file bind-mount: %w", err) - } - } - // Nothing left to do. - return dest, nil - } - - case "tmpfs": - // If the original target exists, copy the mode for the tmpfs mount. - if stat, err := os.Stat(dest); err == nil { - dt := fmt.Sprintf("mode=%04o", syscallMode(stat.Mode())) - if m.Data != "" { - dt = dt + "," + m.Data - } - m.Data = dt - - // Nothing left to do. - return dest, nil - } - } - - if err := utils.MkdirAllInRoot(rootfs, dest, 0o755); err != nil { - return "", err - } - return dest, nil -} - -func mountToRootfs(m *configs.Mount, c *mountConfig) error { - rootfs := c.root - - // procfs and sysfs are special because we need to ensure they are actually - // mounted on a specific path in a container without any funny business. - switch m.Device { - case "proc", "sysfs": - // If the destination already exists and is not a directory, we bail - // out. This is to avoid mounting through a symlink or similar -- which - // has been a "fun" attack scenario in the past. - // TODO: This won't be necessary once we switch to libpathrs and we can - // stop all of these symlink-exchange attacks. - dest := filepath.Clean(m.Destination) - if !strings.HasPrefix(dest, rootfs) { - // Do not use securejoin as it resolves symlinks. - dest = filepath.Join(rootfs, dest) - } - if fi, err := os.Lstat(dest); err != nil { - if !os.IsNotExist(err) { - return err - } - } else if !fi.IsDir() { - return fmt.Errorf("filesystem %q must be mounted on ordinary directory", m.Device) - } - if err := utils.MkdirAllInRoot(rootfs, dest, 0o755); err != nil { - return err - } - // Selinux kernels do not support labeling of /proc or /sys. - return mountPropagate(m, rootfs, "", nil) - } - - mountFd := c.fd - dest, err := createMountpoint(rootfs, m, mountFd, m.Source) - if err != nil { - return fmt.Errorf("create mount destination for %s mount: %w", m.Destination, err) - } - mountLabel := c.label - - switch m.Device { - case "mqueue": - if err := mountPropagate(m, rootfs, "", nil); err != nil { - return err - } - return label.SetFileLabel(dest, mountLabel) - case "tmpfs": - if m.Extensions&configs.EXT_COPYUP == configs.EXT_COPYUP { - err = doTmpfsCopyUp(m, rootfs, mountLabel) - } else { - err = mountPropagate(m, rootfs, mountLabel, nil) - } - return err - case "bind": - if err := mountPropagate(m, rootfs, mountLabel, mountFd); err != nil { - return err - } - // bind mount won't change mount options, we need remount to make mount options effective. - // first check that we have non-default options required before attempting a remount - if m.Flags&^(unix.MS_REC|unix.MS_REMOUNT|unix.MS_BIND) != 0 { - // only remount if unique mount options are set - if err := remount(m, rootfs, mountFd); err != nil { - return err - } - } - - if m.Relabel != "" { - if err := label.Validate(m.Relabel); err != nil { - return err - } - shared := label.IsShared(m.Relabel) - if err := label.Relabel(m.Source, mountLabel, shared); err != nil { - return err - } - } - case "cgroup": - if cgroups.IsCgroup2UnifiedMode() { - return mountCgroupV2(m, c) - } - return mountCgroupV1(m, c) - default: - return mountPropagate(m, rootfs, mountLabel, mountFd) - } - if err := setRecAttr(m, rootfs); err != nil { - return err - } - return nil -} - -func getCgroupMounts(m *configs.Mount) ([]*configs.Mount, error) { - mounts, err := cgroups.GetCgroupMounts(false) - if err != nil { - return nil, err - } - - cgroupPaths, err := cgroups.ParseCgroupFile("/proc/self/cgroup") - if err != nil { - return nil, err - } - - var binds []*configs.Mount - - for _, mm := range mounts { - dir, err := mm.GetOwnCgroup(cgroupPaths) - if err != nil { - return nil, err - } - relDir, err := filepath.Rel(mm.Root, dir) - if err != nil { - return nil, err - } - binds = append(binds, &configs.Mount{ - Device: "bind", - Source: filepath.Join(mm.Mountpoint, relDir), - Destination: filepath.Join(m.Destination, filepath.Base(mm.Mountpoint)), - Flags: unix.MS_BIND | unix.MS_REC | m.Flags, - PropagationFlags: m.PropagationFlags, - }) - } - - return binds, nil -} - -// Taken from . If a file is on a filesystem of type -// PROC_SUPER_MAGIC, we're guaranteed that only the root of the superblock will -// have this inode number. -const procRootIno = 1 - -// checkProcMount checks to ensure that the mount destination is not over the -// top of /proc. dest is required to be an abs path and have any symlinks -// resolved before calling this function. -// -// source is "" when doing criu restores. -func checkProcMount(rootfs, dest string, m *configs.Mount, source string) error { - const procPath = "/proc" - path, err := filepath.Rel(filepath.Join(rootfs, procPath), dest) - if err != nil { - return err - } - // pass if the mount path is located outside of /proc - if strings.HasPrefix(path, "..") { - return nil - } - if path == "." { - // Skip this check for criu restores. - // NOTE: This is a special case kept from the original implementation, - // only present for the 1.1.z branch to avoid any possible breakage in - // a patch release. This check was removed in commit cdff09ab8751 - // ("rootfs: fix 'can we mount on top of /proc' check") in 1.2, because - // it doesn't make sense with the new IsBind()-based checks. - if source == "" { - return nil - } - // Only allow bind-mounts on top of /proc, and only if the source is a - // procfs mount. - if m.IsBind() { - var fsSt unix.Statfs_t - if err := unix.Statfs(source, &fsSt); err != nil { - return &os.PathError{Op: "statfs", Path: source, Err: err} - } - if fsSt.Type == unix.PROC_SUPER_MAGIC { - var uSt unix.Stat_t - if err := unix.Stat(source, &uSt); err != nil { - return &os.PathError{Op: "stat", Path: source, Err: err} - } - if uSt.Ino != procRootIno { - // We cannot error out in this case, because we've - // supported these kinds of mounts for a long time. - // However, we would expect users to bind-mount the root of - // a real procfs on top of /proc in the container. We might - // want to block this in the future. - logrus.Warnf("bind-mount %v (source %v) is of type procfs but is not the root of a procfs (inode %d). Future versions of runc might block this configuration -- please report an issue to if you see this warning.", dest, source, uSt.Ino) - } - return nil - } - } else if m.Device == "proc" { - // Fresh procfs-type mounts are always safe to mount on top of /proc. - return nil - } - return fmt.Errorf("%q cannot be mounted because it is not of type proc", dest) - } - - // Here dest is definitely under /proc. Do not allow those, - // except for a few specific entries emulated by lxcfs. - validProcMounts := []string{ - "/proc/cpuinfo", - "/proc/diskstats", - "/proc/meminfo", - "/proc/stat", - "/proc/swaps", - "/proc/uptime", - "/proc/loadavg", - "/proc/slabinfo", - "/proc/net/dev", - "/proc/sys/kernel/ns_last_pid", - "/proc/sys/crypto/fips_enabled", - } - for _, valid := range validProcMounts { - path, err := filepath.Rel(filepath.Join(rootfs, valid), dest) - if err != nil { - return err - } - if path == "." { - return nil - } - } - - return fmt.Errorf("%q cannot be mounted because it is inside /proc", dest) -} - -func setupDevSymlinks(rootfs string) error { - links := [][2]string{ - {"/proc/self/fd", "/dev/fd"}, - {"/proc/self/fd/0", "/dev/stdin"}, - {"/proc/self/fd/1", "/dev/stdout"}, - {"/proc/self/fd/2", "/dev/stderr"}, - } - // kcore support can be toggled with CONFIG_PROC_KCORE; only create a symlink - // in /dev if it exists in /proc. - if _, err := os.Stat("/proc/kcore"); err == nil { - links = append(links, [2]string{"/proc/kcore", "/dev/core"}) - } - for _, link := range links { - var ( - src = link[0] - dst = filepath.Join(rootfs, link[1]) - ) - if err := os.Symlink(src, dst); err != nil && !os.IsExist(err) { - return err - } - } - return nil -} - -// If stdin, stdout, and/or stderr are pointing to `/dev/null` in the parent's rootfs -// this method will make them point to `/dev/null` in this container's rootfs. This -// needs to be called after we chroot/pivot into the container's rootfs so that any -// symlinks are resolved locally. -func reOpenDevNull() error { - var stat, devNullStat unix.Stat_t - file, err := os.OpenFile("/dev/null", os.O_RDWR, 0) - if err != nil { - return err - } - defer file.Close() //nolint: errcheck - if err := unix.Fstat(int(file.Fd()), &devNullStat); err != nil { - return &os.PathError{Op: "fstat", Path: file.Name(), Err: err} - } - for fd := 0; fd < 3; fd++ { - if err := unix.Fstat(fd, &stat); err != nil { - return &os.PathError{Op: "fstat", Path: "fd " + strconv.Itoa(fd), Err: err} - } - if stat.Rdev == devNullStat.Rdev { - // Close and re-open the fd. - if err := unix.Dup3(int(file.Fd()), fd, 0); err != nil { - return &os.PathError{ - Op: "dup3", - Path: "fd " + strconv.Itoa(int(file.Fd())), - Err: err, - } - } - } - } - return nil -} - -// Create the device nodes in the container. -func createDevices(config *configs.Config) error { - useBindMount := userns.RunningInUserNS() || config.Namespaces.Contains(configs.NEWUSER) - oldMask := unix.Umask(0o000) - for _, node := range config.Devices { - - // The /dev/ptmx device is setup by setupPtmx() - if utils.CleanPath(node.Path) == "/dev/ptmx" { - continue - } - - // containers running in a user namespace are not allowed to mknod - // devices so we can just bind mount it from the host. - if err := createDeviceNode(config.Rootfs, node, useBindMount); err != nil { - unix.Umask(oldMask) - return err - } - } - unix.Umask(oldMask) - return nil -} - -func bindMountDeviceNode(rootfs, dest string, node *devices.Device) error { - f, err := os.Create(dest) - if err != nil && !os.IsExist(err) { - return err - } - if f != nil { - _ = f.Close() - } - return utils.WithProcfd(rootfs, dest, func(procfd string) error { - return mount(node.Path, dest, procfd, "bind", unix.MS_BIND, "") - }) -} - -// Creates the device node in the rootfs of the container. -func createDeviceNode(rootfs string, node *devices.Device, bind bool) error { - if node.Path == "" { - // The node only exists for cgroup reasons, ignore it here. - return nil - } - dest, err := securejoin.SecureJoin(rootfs, node.Path) - if err != nil { - return err - } - if dest == rootfs { - return fmt.Errorf("%w: mknod over rootfs", errRootfsToFile) - } - if err := utils.MkdirAllInRoot(rootfs, filepath.Dir(dest), 0o755); err != nil { - return err - } - if bind { - return bindMountDeviceNode(rootfs, dest, node) - } - if err := mknodDevice(dest, node); err != nil { - if errors.Is(err, os.ErrExist) { - return nil - } else if errors.Is(err, os.ErrPermission) { - return bindMountDeviceNode(rootfs, dest, node) - } - return err - } - return nil -} - -func mknodDevice(dest string, node *devices.Device) error { - fileMode := node.FileMode - switch node.Type { - case devices.BlockDevice: - fileMode |= unix.S_IFBLK - case devices.CharDevice: - fileMode |= unix.S_IFCHR - case devices.FifoDevice: - fileMode |= unix.S_IFIFO - default: - return fmt.Errorf("%c is not a valid device type for device %s", node.Type, node.Path) - } - dev, err := node.Mkdev() - if err != nil { - return err - } - if err := unix.Mknod(dest, uint32(fileMode), int(dev)); err != nil { - return &os.PathError{Op: "mknod", Path: dest, Err: err} - } - return os.Chown(dest, int(node.Uid), int(node.Gid)) -} - -// rootfsParentMountPrivate ensures rootfs parent mount is private. -// This is needed for two reasons: -// - pivot_root() will fail if parent mount is shared; -// - when we bind mount rootfs, if its parent is not private, the new mount -// will propagate (leak!) to parent namespace and we don't want that. -func rootfsParentMountPrivate(path string) error { - var err error - // Assuming path is absolute and clean (this is checked in - // libcontainer/validate). Any error other than EINVAL means we failed, - // and EINVAL means this is not a mount point, so traverse up until we - // find one. - for { - err = unix.Mount("", path, "", unix.MS_PRIVATE, "") - if err == nil { - return nil - } - if err != unix.EINVAL || path == "/" { //nolint:errorlint // unix errors are bare - break - } - path = filepath.Dir(path) - } - return &mountError{ - op: "remount-private", - target: path, - flags: unix.MS_PRIVATE, - err: err, - } -} - -func prepareRoot(config *configs.Config) error { - flag := unix.MS_SLAVE | unix.MS_REC - if config.RootPropagation != 0 { - flag = config.RootPropagation - } - if err := mount("", "/", "", "", uintptr(flag), ""); err != nil { - return err - } - - if err := rootfsParentMountPrivate(config.Rootfs); err != nil { - return err - } - - return mount(config.Rootfs, config.Rootfs, "", "bind", unix.MS_BIND|unix.MS_REC, "") -} - -func setReadonly() error { - flags := uintptr(unix.MS_BIND | unix.MS_REMOUNT | unix.MS_RDONLY) - - err := mount("", "/", "", "", flags, "") - if err == nil { - return nil - } - var s unix.Statfs_t - if err := unix.Statfs("/", &s); err != nil { - return &os.PathError{Op: "statfs", Path: "/", Err: err} - } - flags |= uintptr(s.Flags) - return mount("", "/", "", "", flags, "") -} - -func setupPtmx(config *configs.Config) error { - ptmx := filepath.Join(config.Rootfs, "dev/ptmx") - if err := os.Remove(ptmx); err != nil && !os.IsNotExist(err) { - return err - } - if err := os.Symlink("pts/ptmx", ptmx); err != nil { - return err - } - return nil -} - -// pivotRoot will call pivot_root such that rootfs becomes the new root -// filesystem, and everything else is cleaned up. -func pivotRoot(rootfs string) error { - // While the documentation may claim otherwise, pivot_root(".", ".") is - // actually valid. What this results in is / being the new root but - // /proc/self/cwd being the old root. Since we can play around with the cwd - // with pivot_root this allows us to pivot without creating directories in - // the rootfs. Shout-outs to the LXC developers for giving us this idea. - - oldroot, err := unix.Open("/", unix.O_DIRECTORY|unix.O_RDONLY, 0) - if err != nil { - return &os.PathError{Op: "open", Path: "/", Err: err} - } - defer unix.Close(oldroot) //nolint: errcheck - - newroot, err := unix.Open(rootfs, unix.O_DIRECTORY|unix.O_RDONLY, 0) - if err != nil { - return &os.PathError{Op: "open", Path: rootfs, Err: err} - } - defer unix.Close(newroot) //nolint: errcheck - - // Change to the new root so that the pivot_root actually acts on it. - if err := unix.Fchdir(newroot); err != nil { - return &os.PathError{Op: "fchdir", Path: "fd " + strconv.Itoa(newroot), Err: err} - } - - if err := unix.PivotRoot(".", "."); err != nil { - return &os.PathError{Op: "pivot_root", Path: ".", Err: err} - } - - // Currently our "." is oldroot (according to the current kernel code). - // However, purely for safety, we will fchdir(oldroot) since there isn't - // really any guarantee from the kernel what /proc/self/cwd will be after a - // pivot_root(2). - - if err := unix.Fchdir(oldroot); err != nil { - return &os.PathError{Op: "fchdir", Path: "fd " + strconv.Itoa(oldroot), Err: err} - } - - // Make oldroot rslave to make sure our unmounts don't propagate to the - // host (and thus bork the machine). We don't use rprivate because this is - // known to cause issues due to races where we still have a reference to a - // mount while a process in the host namespace are trying to operate on - // something they think has no mounts (devicemapper in particular). - if err := mount("", ".", "", "", unix.MS_SLAVE|unix.MS_REC, ""); err != nil { - return err - } - // Perform the unmount. MNT_DETACH allows us to unmount /proc/self/cwd. - if err := unmount(".", unix.MNT_DETACH); err != nil { - return err - } - - // Switch back to our shiny new root. - if err := unix.Chdir("/"); err != nil { - return &os.PathError{Op: "chdir", Path: "/", Err: err} - } - return nil -} - -func msMoveRoot(rootfs string) error { - // Before we move the root and chroot we have to mask all "full" sysfs and - // procfs mounts which exist on the host. This is because while the kernel - // has protections against mounting procfs if it has masks, when using - // chroot(2) the *host* procfs mount is still reachable in the mount - // namespace and the kernel permits procfs mounts inside --no-pivot - // containers. - // - // Users shouldn't be using --no-pivot except in exceptional circumstances, - // but to avoid such a trivial security flaw we apply a best-effort - // protection here. The kernel only allows a mount of a pseudo-filesystem - // like procfs or sysfs if there is a *full* mount (the root of the - // filesystem is mounted) without any other locked mount points covering a - // subtree of the mount. - // - // So we try to unmount (or mount tmpfs on top of) any mountpoint which is - // a full mount of either sysfs or procfs (since those are the most - // concerning filesystems to us). - mountinfos, err := mountinfo.GetMounts(func(info *mountinfo.Info) (skip, stop bool) { - // Collect every sysfs and procfs filesystem, except for those which - // are non-full mounts or are inside the rootfs of the container. - if info.Root != "/" || - (info.FSType != "proc" && info.FSType != "sysfs") || - strings.HasPrefix(info.Mountpoint, rootfs) { - skip = true - } - return - }) - if err != nil { - return err - } - for _, info := range mountinfos { - p := info.Mountpoint - // Be sure umount events are not propagated to the host. - if err := mount("", p, "", "", unix.MS_SLAVE|unix.MS_REC, ""); err != nil { - if errors.Is(err, unix.ENOENT) { - // If the mountpoint doesn't exist that means that we've - // already blasted away some parent directory of the mountpoint - // and so we don't care about this error. - continue - } - return err - } - if err := unmount(p, unix.MNT_DETACH); err != nil { - if !errors.Is(err, unix.EINVAL) && !errors.Is(err, unix.EPERM) { - return err - } else { - // If we have not privileges for umounting (e.g. rootless), then - // cover the path. - if err := mount("tmpfs", p, "", "tmpfs", 0, ""); err != nil { - return err - } - } - } - } - - // Move the rootfs on top of "/" in our mount namespace. - if err := mount(rootfs, "/", "", "", unix.MS_MOVE, ""); err != nil { - return err - } - return chroot() -} - -func chroot() error { - if err := unix.Chroot("."); err != nil { - return &os.PathError{Op: "chroot", Path: ".", Err: err} - } - if err := unix.Chdir("/"); err != nil { - return &os.PathError{Op: "chdir", Path: "/", Err: err} - } - return nil -} - -// readonlyPath will make a path read only. -func readonlyPath(path string) error { - if err := mount(path, path, "", "", unix.MS_BIND|unix.MS_REC, ""); err != nil { - if errors.Is(err, os.ErrNotExist) { - return nil - } - return err - } - - var s unix.Statfs_t - if err := unix.Statfs(path, &s); err != nil { - return &os.PathError{Op: "statfs", Path: path, Err: err} - } - flags := uintptr(s.Flags) & (unix.MS_NOSUID | unix.MS_NODEV | unix.MS_NOEXEC) - - if err := mount(path, path, "", "", flags|unix.MS_BIND|unix.MS_REMOUNT|unix.MS_RDONLY, ""); err != nil { - return err - } - - return nil -} - -// remountReadonly will remount an existing mount point and ensure that it is read-only. -func remountReadonly(m *configs.Mount) error { - var ( - dest = m.Destination - flags = m.Flags - ) - for i := 0; i < 5; i++ { - // There is a special case in the kernel for - // MS_REMOUNT | MS_BIND, which allows us to change only the - // flags even as an unprivileged user (i.e. user namespace) - // assuming we don't drop any security related flags (nodev, - // nosuid, etc.). So, let's use that case so that we can do - // this re-mount without failing in a userns. - flags |= unix.MS_REMOUNT | unix.MS_BIND | unix.MS_RDONLY - if err := mount("", dest, "", "", uintptr(flags), ""); err != nil { - if errors.Is(err, unix.EBUSY) { - time.Sleep(100 * time.Millisecond) - continue - } - return err - } - return nil - } - return fmt.Errorf("unable to mount %s as readonly max retries reached", dest) -} - -// maskPath masks the top of the specified path inside a container to avoid -// security issues from processes reading information from non-namespace aware -// mounts ( proc/kcore ). -// For files, maskPath bind mounts /dev/null over the top of the specified path. -// For directories, maskPath mounts read-only tmpfs over the top of the specified path. -func maskPath(path string, mountLabel string) error { - if err := mount("/dev/null", path, "", "", unix.MS_BIND, ""); err != nil && !errors.Is(err, os.ErrNotExist) { - if errors.Is(err, unix.ENOTDIR) { - return mount("tmpfs", path, "", "tmpfs", unix.MS_RDONLY, label.FormatMountLabel("", mountLabel)) - } - return err - } - return nil -} - -// writeSystemProperty writes the value to a path under /proc/sys as determined from the key. -// For e.g. net.ipv4.ip_forward translated to /proc/sys/net/ipv4/ip_forward. -func writeSystemProperty(key, value string) error { - keyPath := strings.Replace(key, ".", "/", -1) - return os.WriteFile(path.Join("/proc/sys", keyPath), []byte(value), 0o644) -} - -func remount(m *configs.Mount, rootfs string, mountFd *int) error { - source := m.Source - if mountFd != nil { - source = "/proc/self/fd/" + strconv.Itoa(*mountFd) - } - - return utils.WithProcfd(rootfs, m.Destination, func(procfd string) error { - flags := uintptr(m.Flags | unix.MS_REMOUNT) - err := mount(source, m.Destination, procfd, m.Device, flags, "") - if err == nil { - return nil - } - // Check if the source has ro flag... - var s unix.Statfs_t - if err := unix.Statfs(source, &s); err != nil { - return &os.PathError{Op: "statfs", Path: source, Err: err} - } - if s.Flags&unix.MS_RDONLY != unix.MS_RDONLY { - return err - } - // ... and retry the mount with ro flag set. - flags |= unix.MS_RDONLY - return mount(source, m.Destination, procfd, m.Device, flags, "") - }) -} - -// Do the mount operation followed by additional mounts required to take care -// of propagation flags. This will always be scoped inside the container rootfs. -func mountPropagate(m *configs.Mount, rootfs string, mountLabel string, mountFd *int) error { - var ( - data = label.FormatMountLabel(m.Data, mountLabel) - flags = m.Flags - ) - // Delay mounting the filesystem read-only if we need to do further - // operations on it. We need to set up files in "/dev", and other tmpfs - // mounts may need to be chmod-ed after mounting. These mounts will be - // remounted ro later in finalizeRootfs(), if necessary. - if m.Device == "tmpfs" || utils.CleanPath(m.Destination) == "/dev" { - flags &= ^unix.MS_RDONLY - } - - // Because the destination is inside a container path which might be - // mutating underneath us, we verify that we are actually going to mount - // inside the container with WithProcfd() -- mounting through a procfd - // mounts on the target. - source := m.Source - if mountFd != nil { - source = "/proc/self/fd/" + strconv.Itoa(*mountFd) - } - - if err := utils.WithProcfd(rootfs, m.Destination, func(procfd string) error { - return mount(source, m.Destination, procfd, m.Device, uintptr(flags), data) - }); err != nil { - return err - } - // We have to apply mount propagation flags in a separate WithProcfd() call - // because the previous call invalidates the passed procfd -- the mount - // target needs to be re-opened. - if err := utils.WithProcfd(rootfs, m.Destination, func(procfd string) error { - for _, pflag := range m.PropagationFlags { - if err := mount("", m.Destination, procfd, "", uintptr(pflag), ""); err != nil { - return err - } - } - return nil - }); err != nil { - return fmt.Errorf("change mount propagation through procfd: %w", err) - } - return nil -} - -func setRecAttr(m *configs.Mount, rootfs string) error { - if m.RecAttr == nil { - return nil - } - return utils.WithProcfd(rootfs, m.Destination, func(procfd string) error { - return unix.MountSetattr(-1, procfd, unix.AT_RECURSIVE, m.RecAttr) - }) -} diff --git a/vendor/github.com/opencontainers/runc/libcontainer/seccomp/config.go b/vendor/github.com/opencontainers/runc/libcontainer/seccomp/config.go deleted file mode 100644 index 2b15576ac90..00000000000 --- a/vendor/github.com/opencontainers/runc/libcontainer/seccomp/config.go +++ /dev/null @@ -1,113 +0,0 @@ -package seccomp - -import ( - "fmt" - "sort" - - "github.com/opencontainers/runc/libcontainer/configs" -) - -var operators = map[string]configs.Operator{ - "SCMP_CMP_NE": configs.NotEqualTo, - "SCMP_CMP_LT": configs.LessThan, - "SCMP_CMP_LE": configs.LessThanOrEqualTo, - "SCMP_CMP_EQ": configs.EqualTo, - "SCMP_CMP_GE": configs.GreaterThanOrEqualTo, - "SCMP_CMP_GT": configs.GreaterThan, - "SCMP_CMP_MASKED_EQ": configs.MaskEqualTo, -} - -// KnownOperators returns the list of the known operations. -// Used by `runc features`. -func KnownOperators() []string { - var res []string - for k := range operators { - res = append(res, k) - } - sort.Strings(res) - return res -} - -var actions = map[string]configs.Action{ - "SCMP_ACT_KILL": configs.Kill, - "SCMP_ACT_ERRNO": configs.Errno, - "SCMP_ACT_TRAP": configs.Trap, - "SCMP_ACT_ALLOW": configs.Allow, - "SCMP_ACT_TRACE": configs.Trace, - "SCMP_ACT_LOG": configs.Log, - "SCMP_ACT_NOTIFY": configs.Notify, - "SCMP_ACT_KILL_THREAD": configs.KillThread, - "SCMP_ACT_KILL_PROCESS": configs.KillProcess, -} - -// KnownActions returns the list of the known actions. -// Used by `runc features`. -func KnownActions() []string { - var res []string - for k := range actions { - res = append(res, k) - } - sort.Strings(res) - return res -} - -var archs = map[string]string{ - "SCMP_ARCH_X86": "x86", - "SCMP_ARCH_X86_64": "amd64", - "SCMP_ARCH_X32": "x32", - "SCMP_ARCH_ARM": "arm", - "SCMP_ARCH_AARCH64": "arm64", - "SCMP_ARCH_MIPS": "mips", - "SCMP_ARCH_MIPS64": "mips64", - "SCMP_ARCH_MIPS64N32": "mips64n32", - "SCMP_ARCH_MIPSEL": "mipsel", - "SCMP_ARCH_MIPSEL64": "mipsel64", - "SCMP_ARCH_MIPSEL64N32": "mipsel64n32", - "SCMP_ARCH_PPC": "ppc", - "SCMP_ARCH_PPC64": "ppc64", - "SCMP_ARCH_PPC64LE": "ppc64le", - "SCMP_ARCH_RISCV64": "riscv64", - "SCMP_ARCH_S390": "s390", - "SCMP_ARCH_S390X": "s390x", -} - -// KnownArchs returns the list of the known archs. -// Used by `runc features`. -func KnownArchs() []string { - var res []string - for k := range archs { - res = append(res, k) - } - sort.Strings(res) - return res -} - -// ConvertStringToOperator converts a string into a Seccomp comparison operator. -// Comparison operators use the names they are assigned by Libseccomp's header. -// Attempting to convert a string that is not a valid operator results in an -// error. -func ConvertStringToOperator(in string) (configs.Operator, error) { - if op, ok := operators[in]; ok { - return op, nil - } - return 0, fmt.Errorf("string %s is not a valid operator for seccomp", in) -} - -// ConvertStringToAction converts a string into a Seccomp rule match action. -// Actions use the names they are assigned in Libseccomp's header. -// Attempting to convert a string that is not a valid action results in an -// error. -func ConvertStringToAction(in string) (configs.Action, error) { - if act, ok := actions[in]; ok { - return act, nil - } - return 0, fmt.Errorf("string %s is not a valid action for seccomp", in) -} - -// ConvertStringToArch converts a string into a Seccomp comparison arch. -func ConvertStringToArch(in string) (string, error) { - if arch, ok := archs[in]; ok { - return arch, nil - } - return "", fmt.Errorf("string %s is not a valid arch for seccomp", in) -} diff --git a/vendor/github.com/opencontainers/runc/libcontainer/seccomp/patchbpf/enosys_linux.go b/vendor/github.com/opencontainers/runc/libcontainer/seccomp/patchbpf/enosys_linux.go deleted file mode 100644 index d459ba8792c..00000000000 --- a/vendor/github.com/opencontainers/runc/libcontainer/seccomp/patchbpf/enosys_linux.go +++ /dev/null @@ -1,721 +0,0 @@ -//go:build cgo && seccomp -// +build cgo,seccomp - -package patchbpf - -import ( - "bytes" - "encoding/binary" - "errors" - "fmt" - "io" - "os" - "runtime" - "unsafe" - - libseccomp "github.com/seccomp/libseccomp-golang" - "github.com/sirupsen/logrus" - "golang.org/x/net/bpf" - "golang.org/x/sys/unix" - - "github.com/opencontainers/runc/libcontainer/configs" - "github.com/opencontainers/runc/libcontainer/utils" -) - -// #cgo pkg-config: libseccomp -/* -#include -#include -#include -#include - -const uint32_t C_ACT_ERRNO_ENOSYS = SCMP_ACT_ERRNO(ENOSYS); - -// Copied from . - -#ifndef SECCOMP_SET_MODE_FILTER -# define SECCOMP_SET_MODE_FILTER 1 -#endif -const uintptr_t C_SET_MODE_FILTER = SECCOMP_SET_MODE_FILTER; - -#ifndef SECCOMP_FILTER_FLAG_LOG -# define SECCOMP_FILTER_FLAG_LOG (1UL << 1) -#endif -const uintptr_t C_FILTER_FLAG_LOG = SECCOMP_FILTER_FLAG_LOG; - -#ifndef SECCOMP_FILTER_FLAG_NEW_LISTENER -# define SECCOMP_FILTER_FLAG_NEW_LISTENER (1UL << 3) -#endif -const uintptr_t C_FILTER_FLAG_NEW_LISTENER = SECCOMP_FILTER_FLAG_NEW_LISTENER; - -#ifndef AUDIT_ARCH_RISCV64 -#ifndef EM_RISCV -#define EM_RISCV 243 -#endif -#define AUDIT_ARCH_RISCV64 (EM_RISCV|__AUDIT_ARCH_64BIT|__AUDIT_ARCH_LE) -#endif - -// We use the AUDIT_ARCH_* values because those are the ones used by the kernel -// and SCMP_ARCH_* sometimes has fake values (such as SCMP_ARCH_X32). But we -// use so we get libseccomp's fallback definitions of AUDIT_ARCH_*. - -const uint32_t C_AUDIT_ARCH_I386 = AUDIT_ARCH_I386; -const uint32_t C_AUDIT_ARCH_X86_64 = AUDIT_ARCH_X86_64; -const uint32_t C_AUDIT_ARCH_ARM = AUDIT_ARCH_ARM; -const uint32_t C_AUDIT_ARCH_AARCH64 = AUDIT_ARCH_AARCH64; -const uint32_t C_AUDIT_ARCH_MIPS = AUDIT_ARCH_MIPS; -const uint32_t C_AUDIT_ARCH_MIPS64 = AUDIT_ARCH_MIPS64; -const uint32_t C_AUDIT_ARCH_MIPS64N32 = AUDIT_ARCH_MIPS64N32; -const uint32_t C_AUDIT_ARCH_MIPSEL = AUDIT_ARCH_MIPSEL; -const uint32_t C_AUDIT_ARCH_MIPSEL64 = AUDIT_ARCH_MIPSEL64; -const uint32_t C_AUDIT_ARCH_MIPSEL64N32 = AUDIT_ARCH_MIPSEL64N32; -const uint32_t C_AUDIT_ARCH_PPC = AUDIT_ARCH_PPC; -const uint32_t C_AUDIT_ARCH_PPC64 = AUDIT_ARCH_PPC64; -const uint32_t C_AUDIT_ARCH_PPC64LE = AUDIT_ARCH_PPC64LE; -const uint32_t C_AUDIT_ARCH_S390 = AUDIT_ARCH_S390; -const uint32_t C_AUDIT_ARCH_S390X = AUDIT_ARCH_S390X; -const uint32_t C_AUDIT_ARCH_RISCV64 = AUDIT_ARCH_RISCV64; -*/ -import "C" - -var retErrnoEnosys = uint32(C.C_ACT_ERRNO_ENOSYS) - -// This syscall is used for multiplexing "large" syscalls on s390(x). Unknown -// syscalls will end up with this syscall number, so we need to explicitly -// return -ENOSYS for this syscall on those architectures. -const s390xMultiplexSyscall libseccomp.ScmpSyscall = 0 - -func isAllowAction(action configs.Action) bool { - switch action { - // Trace is considered an "allow" action because a good tracer should - // support future syscalls (by handling -ENOSYS on its own), and giving - // -ENOSYS will be disruptive for emulation. - case configs.Allow, configs.Log, configs.Trace: - return true - default: - return false - } -} - -func parseProgram(rdr io.Reader) ([]bpf.RawInstruction, error) { - var program []bpf.RawInstruction -loop: - for { - // Read the next instruction. We have to use NativeEndian because - // seccomp_export_bpf outputs the program in *host* endian-ness. - var insn unix.SockFilter - if err := binary.Read(rdr, utils.NativeEndian, &insn); err != nil { - if errors.Is(err, io.EOF) { - // Parsing complete. - break loop - } - if errors.Is(err, io.ErrUnexpectedEOF) { - // Parsing stopped mid-instruction. - return nil, fmt.Errorf("program parsing halted mid-instruction: %w", err) - } - // All other errors. - return nil, fmt.Errorf("error parsing instructions: %w", err) - } - program = append(program, bpf.RawInstruction{ - Op: insn.Code, - Jt: insn.Jt, - Jf: insn.Jf, - K: insn.K, - }) - } - return program, nil -} - -func disassembleFilter(filter *libseccomp.ScmpFilter) ([]bpf.Instruction, error) { - rdr, wtr, err := os.Pipe() - if err != nil { - return nil, fmt.Errorf("error creating scratch pipe: %w", err) - } - defer wtr.Close() - defer rdr.Close() - - readerBuffer := new(bytes.Buffer) - errChan := make(chan error, 1) - go func() { - _, err := io.Copy(readerBuffer, rdr) - errChan <- err - close(errChan) - }() - - if err := filter.ExportBPF(wtr); err != nil { - return nil, fmt.Errorf("error exporting BPF: %w", err) - } - // Close so that the reader actually gets EOF. - _ = wtr.Close() - - if copyErr := <-errChan; copyErr != nil { - return nil, fmt.Errorf("error reading from ExportBPF pipe: %w", copyErr) - } - - // Parse the instructions. - rawProgram, err := parseProgram(readerBuffer) - if err != nil { - return nil, fmt.Errorf("parsing generated BPF filter: %w", err) - } - program, ok := bpf.Disassemble(rawProgram) - if !ok { - return nil, errors.New("could not disassemble entire BPF filter") - } - return program, nil -} - -type linuxAuditArch uint32 - -const invalidArch linuxAuditArch = 0 - -func scmpArchToAuditArch(arch libseccomp.ScmpArch) (linuxAuditArch, error) { - switch arch { - case libseccomp.ArchNative: - // Convert to actual native architecture. - arch, err := libseccomp.GetNativeArch() - if err != nil { - return invalidArch, fmt.Errorf("unable to get native arch: %w", err) - } - return scmpArchToAuditArch(arch) - case libseccomp.ArchX86: - return linuxAuditArch(C.C_AUDIT_ARCH_I386), nil - case libseccomp.ArchAMD64, libseccomp.ArchX32: - // NOTE: x32 is treated like x86_64 except all x32 syscalls have the - // 30th bit of the syscall number set to indicate that it's not a - // normal x86_64 syscall. - return linuxAuditArch(C.C_AUDIT_ARCH_X86_64), nil - case libseccomp.ArchARM: - return linuxAuditArch(C.C_AUDIT_ARCH_ARM), nil - case libseccomp.ArchARM64: - return linuxAuditArch(C.C_AUDIT_ARCH_AARCH64), nil - case libseccomp.ArchMIPS: - return linuxAuditArch(C.C_AUDIT_ARCH_MIPS), nil - case libseccomp.ArchMIPS64: - return linuxAuditArch(C.C_AUDIT_ARCH_MIPS64), nil - case libseccomp.ArchMIPS64N32: - return linuxAuditArch(C.C_AUDIT_ARCH_MIPS64N32), nil - case libseccomp.ArchMIPSEL: - return linuxAuditArch(C.C_AUDIT_ARCH_MIPSEL), nil - case libseccomp.ArchMIPSEL64: - return linuxAuditArch(C.C_AUDIT_ARCH_MIPSEL64), nil - case libseccomp.ArchMIPSEL64N32: - return linuxAuditArch(C.C_AUDIT_ARCH_MIPSEL64N32), nil - case libseccomp.ArchPPC: - return linuxAuditArch(C.C_AUDIT_ARCH_PPC), nil - case libseccomp.ArchPPC64: - return linuxAuditArch(C.C_AUDIT_ARCH_PPC64), nil - case libseccomp.ArchPPC64LE: - return linuxAuditArch(C.C_AUDIT_ARCH_PPC64LE), nil - case libseccomp.ArchS390: - return linuxAuditArch(C.C_AUDIT_ARCH_S390), nil - case libseccomp.ArchS390X: - return linuxAuditArch(C.C_AUDIT_ARCH_S390X), nil - case libseccomp.ArchRISCV64: - return linuxAuditArch(C.C_AUDIT_ARCH_RISCV64), nil - default: - return invalidArch, fmt.Errorf("unknown architecture: %v", arch) - } -} - -type lastSyscallMap map[linuxAuditArch]map[libseccomp.ScmpArch]libseccomp.ScmpSyscall - -// Figure out largest syscall number referenced in the filter for each -// architecture. We will be generating code based on the native architecture -// representation, but SCMP_ARCH_X32 means we have to track cases where the -// same architecture has different largest syscalls based on the mode. -func findLastSyscalls(config *configs.Seccomp) (lastSyscallMap, error) { - scmpArchs := make(map[libseccomp.ScmpArch]struct{}) - for _, ociArch := range config.Architectures { - arch, err := libseccomp.GetArchFromString(ociArch) - if err != nil { - return nil, fmt.Errorf("unable to validate seccomp architecture: %w", err) - } - scmpArchs[arch] = struct{}{} - } - // On architectures like ppc64le, Docker inexplicably doesn't include the - // native architecture in the architecture list which results in no - // architectures being present in the list at all (rendering the ENOSYS - // stub a no-op). So, always include the native architecture. - if nativeScmpArch, err := libseccomp.GetNativeArch(); err != nil { - return nil, fmt.Errorf("unable to get native arch: %w", err) - } else if _, ok := scmpArchs[nativeScmpArch]; !ok { - logrus.Debugf("seccomp: adding implied native architecture %v to config set", nativeScmpArch) - scmpArchs[nativeScmpArch] = struct{}{} - } - logrus.Debugf("seccomp: configured architecture set: %s", scmpArchs) - - // Only loop over architectures which are present in the filter. Any other - // architectures will get the libseccomp bad architecture action anyway. - lastSyscalls := make(lastSyscallMap) - for arch := range scmpArchs { - auditArch, err := scmpArchToAuditArch(arch) - if err != nil { - return nil, fmt.Errorf("cannot map architecture %v to AUDIT_ARCH_ constant: %w", arch, err) - } - - if _, ok := lastSyscalls[auditArch]; !ok { - lastSyscalls[auditArch] = map[libseccomp.ScmpArch]libseccomp.ScmpSyscall{} - } - if _, ok := lastSyscalls[auditArch][arch]; ok { - // Because of ArchNative we may hit the same entry multiple times. - // Just skip it if we've seen this (linuxAuditArch, ScmpArch) - // combination before. - continue - } - - // Find the largest syscall in the filter for this architecture. - var largestSyscall libseccomp.ScmpSyscall - for _, rule := range config.Syscalls { - sysno, err := libseccomp.GetSyscallFromNameByArch(rule.Name, arch) - if err != nil { - // Ignore unknown syscalls. - continue - } - if sysno > largestSyscall { - largestSyscall = sysno - } - } - if largestSyscall != 0 { - logrus.Debugf("seccomp: largest syscall number for arch %v is %v", arch, largestSyscall) - lastSyscalls[auditArch][arch] = largestSyscall - } else { - logrus.Warnf("could not find any syscalls for arch %v", arch) - delete(lastSyscalls[auditArch], arch) - } - } - return lastSyscalls, nil -} - -// FIXME FIXME FIXME -// -// This solution is less than ideal. In the future it would be great to have -// per-arch information about which syscalls were added in which kernel -// versions so we can create far more accurate filter rules (handling holes in -// the syscall table and determining -ENOSYS requirements based on kernel -// minimum version alone. -// -// This implementation can in principle cause issues with syscalls like -// close_range(2) which were added out-of-order in the syscall table between -// kernel releases. -func generateEnosysStub(lastSyscalls lastSyscallMap) ([]bpf.Instruction, error) { - // A jump-table for each linuxAuditArch used to generate the initial - // conditional jumps -- measured from the *END* of the program so they - // remain valid after prepending to the tail. - archJumpTable := map[linuxAuditArch]uint32{} - - // Generate our own -ENOSYS rules for each architecture. They have to be - // generated in reverse (prepended to the tail of the program) because the - // JumpIf jumps need to be computed from the end of the program. - programTail := []bpf.Instruction{ - // Fall-through rules jump into the filter. - bpf.Jump{Skip: 1}, - // Rules which jump to here get -ENOSYS. - bpf.RetConstant{Val: retErrnoEnosys}, - } - - // Generate the syscall -ENOSYS rules. - for auditArch, maxSyscalls := range lastSyscalls { - // The number of instructions from the tail of this section which need - // to be jumped in order to reach the -ENOSYS return. If the section - // does not jump, it will fall through to the actual filter. - baseJumpEnosys := uint32(len(programTail) - 1) - baseJumpFilter := baseJumpEnosys + 1 - - // Add the load instruction for the syscall number -- we jump here - // directly from the arch code so we need to do it here. Sadly we can't - // share this code between architecture branches. - section := []bpf.Instruction{ - // load [0] (syscall number) - bpf.LoadAbsolute{Off: 0, Size: 4}, // NOTE: We assume sizeof(int) == 4. - } - - switch len(maxSyscalls) { - case 0: - // No syscalls found for this arch -- skip it and move on. - continue - case 1: - // Get the only syscall and scmpArch in the map. - var ( - scmpArch libseccomp.ScmpArch - sysno libseccomp.ScmpSyscall - ) - for arch, no := range maxSyscalls { - sysno = no - scmpArch = arch - } - - switch scmpArch { - // Return -ENOSYS for setup(2) on s390(x). This syscall is used for - // multiplexing "large syscall number" syscalls, but if the syscall - // number is not known to the kernel then the syscall number is - // left unchanged (and because it is sysno=0, you'll end up with - // EPERM for syscalls the kernel doesn't know about). - // - // The actual setup(2) syscall is never used by userspace anymore - // (and hasn't existed for decades) outside of this multiplexing - // scheme so returning -ENOSYS is fine. - case libseccomp.ArchS390, libseccomp.ArchS390X: - section = append(section, []bpf.Instruction{ - // jne [setup=0],1 - bpf.JumpIf{ - Cond: bpf.JumpNotEqual, - Val: uint32(s390xMultiplexSyscall), - SkipTrue: 1, - }, - // ret [ENOSYS] - bpf.RetConstant{Val: retErrnoEnosys}, - }...) - } - - // The simplest case just boils down to a single jgt instruction, - // with special handling if baseJumpEnosys is larger than 255 (and - // thus a long jump is required). - var sectionTail []bpf.Instruction - if baseJumpEnosys+1 <= 255 { - sectionTail = []bpf.Instruction{ - // jgt [syscall],[baseJumpEnosys+1] - bpf.JumpIf{ - Cond: bpf.JumpGreaterThan, - Val: uint32(sysno), - SkipTrue: uint8(baseJumpEnosys + 1), - }, - // ja [baseJumpFilter] - bpf.Jump{Skip: baseJumpFilter}, - } - } else { - sectionTail = []bpf.Instruction{ - // jle [syscall],1 - bpf.JumpIf{Cond: bpf.JumpLessOrEqual, Val: uint32(sysno), SkipTrue: 1}, - // ja [baseJumpEnosys+1] - bpf.Jump{Skip: baseJumpEnosys + 1}, - // ja [baseJumpFilter] - bpf.Jump{Skip: baseJumpFilter}, - } - } - - // If we're on x86 we need to add a check for x32 and if we're in - // the wrong mode we jump over the section. - if uint32(auditArch) == uint32(C.C_AUDIT_ARCH_X86_64) { - // Generate a prefix to check the mode. - switch scmpArch { - case libseccomp.ArchAMD64: - sectionTail = append([]bpf.Instruction{ - // jset (1<<30),[len(tail)-1] - bpf.JumpIf{ - Cond: bpf.JumpBitsSet, - Val: 1 << 30, - SkipTrue: uint8(len(sectionTail) - 1), - }, - }, sectionTail...) - case libseccomp.ArchX32: - sectionTail = append([]bpf.Instruction{ - // jset (1<<30),0,[len(tail)-1] - bpf.JumpIf{ - Cond: bpf.JumpBitsNotSet, - Val: 1 << 30, - SkipTrue: uint8(len(sectionTail) - 1), - }, - }, sectionTail...) - default: - return nil, fmt.Errorf("unknown amd64 native architecture %#x", scmpArch) - } - } - - section = append(section, sectionTail...) - case 2: - // x32 and x86_64 are a unique case, we can't handle any others. - if uint32(auditArch) != uint32(C.C_AUDIT_ARCH_X86_64) { - return nil, fmt.Errorf("unknown architecture overlap on native arch %#x", auditArch) - } - - x32sysno, ok := maxSyscalls[libseccomp.ArchX32] - if !ok { - return nil, fmt.Errorf("missing %v in overlapping x86_64 arch: %v", libseccomp.ArchX32, maxSyscalls) - } - x86sysno, ok := maxSyscalls[libseccomp.ArchAMD64] - if !ok { - return nil, fmt.Errorf("missing %v in overlapping x86_64 arch: %v", libseccomp.ArchAMD64, maxSyscalls) - } - - // The x32 ABI indicates that a syscall is being made by an x32 - // process by setting the 30th bit of the syscall number, but we - // need to do some special-casing depending on whether we need to - // do long jumps. - if baseJumpEnosys+2 <= 255 { - // For the simple case we want to have something like: - // jset (1<<30),1 - // jgt [x86 syscall],[baseJumpEnosys+2],1 - // jgt [x32 syscall],[baseJumpEnosys+1] - // ja [baseJumpFilter] - section = append(section, []bpf.Instruction{ - // jset (1<<30),1 - bpf.JumpIf{Cond: bpf.JumpBitsSet, Val: 1 << 30, SkipTrue: 1}, - // jgt [x86 syscall],[baseJumpEnosys+1],1 - bpf.JumpIf{ - Cond: bpf.JumpGreaterThan, - Val: uint32(x86sysno), - SkipTrue: uint8(baseJumpEnosys + 2), SkipFalse: 1, - }, - // jgt [x32 syscall],[baseJumpEnosys] - bpf.JumpIf{ - Cond: bpf.JumpGreaterThan, - Val: uint32(x32sysno), - SkipTrue: uint8(baseJumpEnosys + 1), - }, - // ja [baseJumpFilter] - bpf.Jump{Skip: baseJumpFilter}, - }...) - } else { - // But if the [baseJumpEnosys+2] jump is larger than 255 we - // need to do a long jump like so: - // jset (1<<30),1 - // jgt [x86 syscall],1,2 - // jle [x32 syscall],1 - // ja [baseJumpEnosys+1] - // ja [baseJumpFilter] - section = append(section, []bpf.Instruction{ - // jset (1<<30),1 - bpf.JumpIf{Cond: bpf.JumpBitsSet, Val: 1 << 30, SkipTrue: 1}, - // jgt [x86 syscall],1,2 - bpf.JumpIf{ - Cond: bpf.JumpGreaterThan, - Val: uint32(x86sysno), - SkipTrue: 1, SkipFalse: 2, - }, - // jle [x32 syscall],[baseJumpEnosys] - bpf.JumpIf{ - Cond: bpf.JumpLessOrEqual, - Val: uint32(x32sysno), - SkipTrue: 1, - }, - // ja [baseJumpEnosys+1] - bpf.Jump{Skip: baseJumpEnosys + 1}, - // ja [baseJumpFilter] - bpf.Jump{Skip: baseJumpFilter}, - }...) - } - default: - return nil, fmt.Errorf("invalid number of architecture overlaps: %v", len(maxSyscalls)) - } - - // Prepend this section to the tail. - programTail = append(section, programTail...) - - // Update jump table. - archJumpTable[auditArch] = uint32(len(programTail)) - } - - // Add a dummy "jump to filter" for any architecture we might miss below. - // Such architectures will probably get the BadArch action of the filter - // regardless. - programTail = append([]bpf.Instruction{ - // ja [end of stub and start of filter] - bpf.Jump{Skip: uint32(len(programTail))}, - }, programTail...) - - // Generate the jump rules for each architecture. This has to be done in - // reverse as well for the same reason as above. We add to programTail - // directly because the jumps are impacted by each architecture rule we add - // as well. - // - // TODO: Maybe we want to optimise to avoid long jumps here? So sort the - // architectures based on how large the jumps are going to be, or - // re-sort the candidate architectures each time to make sure that we - // pick the largest jump which is going to be smaller than 255. - for auditArch := range lastSyscalls { - // We jump forwards but the jump table is calculated from the *END*. - jump := uint32(len(programTail)) - archJumpTable[auditArch] - - // Same routine as above -- this is a basic jeq check, complicated - // slightly if it turns out that we need to do a long jump. - if jump <= 255 { - programTail = append([]bpf.Instruction{ - // jeq [arch],[jump] - bpf.JumpIf{ - Cond: bpf.JumpEqual, - Val: uint32(auditArch), - SkipTrue: uint8(jump), - }, - }, programTail...) - } else { - programTail = append([]bpf.Instruction{ - // jne [arch],1 - bpf.JumpIf{ - Cond: bpf.JumpNotEqual, - Val: uint32(auditArch), - SkipTrue: 1, - }, - // ja [jump] - bpf.Jump{Skip: jump}, - }, programTail...) - } - } - - // Prepend the load instruction for the architecture. - programTail = append([]bpf.Instruction{ - // load [4] (architecture) - bpf.LoadAbsolute{Off: 4, Size: 4}, // NOTE: We assume sizeof(int) == 4. - }, programTail...) - - // And that's all folks! - return programTail, nil -} - -func assemble(program []bpf.Instruction) ([]unix.SockFilter, error) { - rawProgram, err := bpf.Assemble(program) - if err != nil { - return nil, fmt.Errorf("error assembling program: %w", err) - } - - // Convert to []unix.SockFilter for unix.SockFilter. - var filter []unix.SockFilter - for _, insn := range rawProgram { - filter = append(filter, unix.SockFilter{ - Code: insn.Op, - Jt: insn.Jt, - Jf: insn.Jf, - K: insn.K, - }) - } - return filter, nil -} - -func generatePatch(config *configs.Seccomp) ([]bpf.Instruction, error) { - // Patch the generated cBPF only when there is not a defaultErrnoRet set - // and it is different from ENOSYS - if config.DefaultErrnoRet != nil && *config.DefaultErrnoRet == uint(retErrnoEnosys) { - return nil, nil - } - // We only add the stub if the default action is not permissive. - if isAllowAction(config.DefaultAction) { - logrus.Debugf("seccomp: skipping -ENOSYS stub filter generation") - return nil, nil - } - - lastSyscalls, err := findLastSyscalls(config) - if err != nil { - return nil, fmt.Errorf("error finding last syscalls for -ENOSYS stub: %w", err) - } - stubProgram, err := generateEnosysStub(lastSyscalls) - if err != nil { - return nil, fmt.Errorf("error generating -ENOSYS stub: %w", err) - } - return stubProgram, nil -} - -func enosysPatchFilter(config *configs.Seccomp, filter *libseccomp.ScmpFilter) ([]unix.SockFilter, error) { - program, err := disassembleFilter(filter) - if err != nil { - return nil, fmt.Errorf("error disassembling original filter: %w", err) - } - - patch, err := generatePatch(config) - if err != nil { - return nil, fmt.Errorf("error generating patch for filter: %w", err) - } - fullProgram := append(patch, program...) - - logrus.Debugf("seccomp: prepending -ENOSYS stub filter to user filter...") - for idx, insn := range patch { - logrus.Debugf(" [%4.1d] %s", idx, insn) - } - logrus.Debugf(" [....] --- original filter ---") - - fprog, err := assemble(fullProgram) - if err != nil { - return nil, fmt.Errorf("error assembling modified filter: %w", err) - } - return fprog, nil -} - -func filterFlags(config *configs.Seccomp, filter *libseccomp.ScmpFilter) (flags uint, noNewPrivs bool, err error) { - // Ignore the error since pre-2.4 libseccomp is treated as API level 0. - apiLevel, _ := libseccomp.GetAPI() - - noNewPrivs, err = filter.GetNoNewPrivsBit() - if err != nil { - return 0, false, fmt.Errorf("unable to fetch no_new_privs filter bit: %w", err) - } - - if apiLevel >= 3 { - if logBit, err := filter.GetLogBit(); err != nil { - return 0, false, fmt.Errorf("unable to fetch SECCOMP_FILTER_FLAG_LOG bit: %w", err) - } else if logBit { - flags |= uint(C.C_FILTER_FLAG_LOG) - } - } - - // TODO: Support seccomp flags not yet added to libseccomp-golang... - - for _, call := range config.Syscalls { - if call.Action == configs.Notify { - flags |= uint(C.C_FILTER_FLAG_NEW_LISTENER) - break - } - } - - return -} - -func sysSeccompSetFilter(flags uint, filter []unix.SockFilter) (fd int, err error) { - fprog := unix.SockFprog{ - Len: uint16(len(filter)), - Filter: &filter[0], - } - fd = -1 // only return a valid fd when C_FILTER_FLAG_NEW_LISTENER is set - // If no seccomp flags were requested we can use the old-school prctl(2). - if flags == 0 { - err = unix.Prctl(unix.PR_SET_SECCOMP, - unix.SECCOMP_MODE_FILTER, - uintptr(unsafe.Pointer(&fprog)), 0, 0) - } else { - fdptr, _, errno := unix.RawSyscall(unix.SYS_SECCOMP, - uintptr(C.C_SET_MODE_FILTER), - uintptr(flags), uintptr(unsafe.Pointer(&fprog))) - if errno != 0 { - err = errno - } - if flags&uint(C.C_FILTER_FLAG_NEW_LISTENER) != 0 { - fd = int(fdptr) - } - } - runtime.KeepAlive(filter) - runtime.KeepAlive(fprog) - return -} - -// PatchAndLoad takes a seccomp configuration and a libseccomp filter which has -// been pre-configured with the set of rules in the seccomp config. It then -// patches said filter to handle -ENOSYS in a much nicer manner than the -// default libseccomp default action behaviour, and loads the patched filter -// into the kernel for the current process. -func PatchAndLoad(config *configs.Seccomp, filter *libseccomp.ScmpFilter) (int, error) { - // Generate a patched filter. - fprog, err := enosysPatchFilter(config, filter) - if err != nil { - return -1, fmt.Errorf("error patching filter: %w", err) - } - - // Get the set of libseccomp flags set. - seccompFlags, noNewPrivs, err := filterFlags(config, filter) - if err != nil { - return -1, fmt.Errorf("unable to fetch seccomp filter flags: %w", err) - } - - // Set no_new_privs if it was requested, though in runc we handle - // no_new_privs separately so warn if we hit this path. - if noNewPrivs { - logrus.Warnf("potentially misconfigured filter -- setting no_new_privs in seccomp path") - if err := unix.Prctl(unix.PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0); err != nil { - return -1, fmt.Errorf("error enabling no_new_privs bit: %w", err) - } - } - - // Finally, load the filter. - fd, err := sysSeccompSetFilter(seccompFlags, fprog) - if err != nil { - return -1, fmt.Errorf("error loading seccomp filter: %w", err) - } - - return fd, nil -} diff --git a/vendor/github.com/opencontainers/runc/libcontainer/seccomp/patchbpf/enosys_unsupported.go b/vendor/github.com/opencontainers/runc/libcontainer/seccomp/patchbpf/enosys_unsupported.go deleted file mode 100644 index d23167ae357..00000000000 --- a/vendor/github.com/opencontainers/runc/libcontainer/seccomp/patchbpf/enosys_unsupported.go +++ /dev/null @@ -1,4 +0,0 @@ -//go:build !linux || !cgo || !seccomp -// +build !linux !cgo !seccomp - -package patchbpf diff --git a/vendor/github.com/opencontainers/runc/libcontainer/seccomp/seccomp_linux.go b/vendor/github.com/opencontainers/runc/libcontainer/seccomp/seccomp_linux.go deleted file mode 100644 index 8c12af72be9..00000000000 --- a/vendor/github.com/opencontainers/runc/libcontainer/seccomp/seccomp_linux.go +++ /dev/null @@ -1,268 +0,0 @@ -//go:build cgo && seccomp -// +build cgo,seccomp - -package seccomp - -import ( - "errors" - "fmt" - - libseccomp "github.com/seccomp/libseccomp-golang" - "github.com/sirupsen/logrus" - "golang.org/x/sys/unix" - - "github.com/opencontainers/runc/libcontainer/configs" - "github.com/opencontainers/runc/libcontainer/seccomp/patchbpf" -) - -var ( - actTrace = libseccomp.ActTrace.SetReturnCode(int16(unix.EPERM)) - actErrno = libseccomp.ActErrno.SetReturnCode(int16(unix.EPERM)) -) - -const ( - // Linux system calls can have at most 6 arguments - syscallMaxArguments int = 6 -) - -// InitSeccomp installs the seccomp filters to be used in the container as -// specified in config. -// Returns the seccomp file descriptor if any of the filters include a -// SCMP_ACT_NOTIFY action, otherwise returns -1. -func InitSeccomp(config *configs.Seccomp) (int, error) { - if config == nil { - return -1, errors.New("cannot initialize Seccomp - nil config passed") - } - - defaultAction, err := getAction(config.DefaultAction, config.DefaultErrnoRet) - if err != nil { - return -1, errors.New("error initializing seccomp - invalid default action") - } - - // Ignore the error since pre-2.4 libseccomp is treated as API level 0. - apiLevel, _ := libseccomp.GetAPI() - for _, call := range config.Syscalls { - if call.Action == configs.Notify { - if apiLevel < 6 { - return -1, fmt.Errorf("seccomp notify unsupported: API level: got %d, want at least 6. Please try with libseccomp >= 2.5.0 and Linux >= 5.7", apiLevel) - } - - // We can't allow the write syscall to notify to the seccomp agent. - // After InitSeccomp() is called, we need to syncParentSeccomp() to write the seccomp fd plain - // number, so the parent sends it to the seccomp agent. If we use SCMP_ACT_NOTIFY on write, we - // never can write the seccomp fd to the parent and therefore the seccomp agent never receives - // the seccomp fd and runc is hang during initialization. - // - // Note that read()/close(), that are also used in syncParentSeccomp(), _can_ use SCMP_ACT_NOTIFY. - // Because we write the seccomp fd on the pipe to the parent, the parent is able to proceed and - // send the seccomp fd to the agent (it is another process and not subject to the seccomp - // filter). We will be blocked on read()/close() inside syncParentSeccomp() but if the seccomp - // agent allows those syscalls to proceed, initialization works just fine and the agent can - // handle future read()/close() syscalls as it wanted. - if call.Name == "write" { - return -1, errors.New("SCMP_ACT_NOTIFY cannot be used for the write syscall") - } - } - } - - // See comment on why write is not allowed. The same reason applies, as this can mean handling write too. - if defaultAction == libseccomp.ActNotify { - return -1, errors.New("SCMP_ACT_NOTIFY cannot be used as default action") - } - - filter, err := libseccomp.NewFilter(defaultAction) - if err != nil { - return -1, fmt.Errorf("error creating filter: %w", err) - } - - // Add extra architectures - for _, arch := range config.Architectures { - scmpArch, err := libseccomp.GetArchFromString(arch) - if err != nil { - return -1, fmt.Errorf("error validating Seccomp architecture: %w", err) - } - if err := filter.AddArch(scmpArch); err != nil { - return -1, fmt.Errorf("error adding architecture to seccomp filter: %w", err) - } - } - - // Unset no new privs bit - if err := filter.SetNoNewPrivsBit(false); err != nil { - return -1, fmt.Errorf("error setting no new privileges: %w", err) - } - - // Add a rule for each syscall - for _, call := range config.Syscalls { - if call == nil { - return -1, errors.New("encountered nil syscall while initializing Seccomp") - } - - if err := matchCall(filter, call, defaultAction); err != nil { - return -1, err - } - } - - seccompFd, err := patchbpf.PatchAndLoad(config, filter) - if err != nil { - return -1, fmt.Errorf("error loading seccomp filter into kernel: %w", err) - } - - return seccompFd, nil -} - -// Convert Libcontainer Action to Libseccomp ScmpAction -func getAction(act configs.Action, errnoRet *uint) (libseccomp.ScmpAction, error) { - switch act { - case configs.Kill, configs.KillThread: - return libseccomp.ActKillThread, nil - case configs.Errno: - if errnoRet != nil { - return libseccomp.ActErrno.SetReturnCode(int16(*errnoRet)), nil - } - return actErrno, nil - case configs.Trap: - return libseccomp.ActTrap, nil - case configs.Allow: - return libseccomp.ActAllow, nil - case configs.Trace: - if errnoRet != nil { - return libseccomp.ActTrace.SetReturnCode(int16(*errnoRet)), nil - } - return actTrace, nil - case configs.Log: - return libseccomp.ActLog, nil - case configs.Notify: - return libseccomp.ActNotify, nil - case configs.KillProcess: - return libseccomp.ActKillProcess, nil - default: - return libseccomp.ActInvalid, errors.New("invalid action, cannot use in rule") - } -} - -// Convert Libcontainer Operator to Libseccomp ScmpCompareOp -func getOperator(op configs.Operator) (libseccomp.ScmpCompareOp, error) { - switch op { - case configs.EqualTo: - return libseccomp.CompareEqual, nil - case configs.NotEqualTo: - return libseccomp.CompareNotEqual, nil - case configs.GreaterThan: - return libseccomp.CompareGreater, nil - case configs.GreaterThanOrEqualTo: - return libseccomp.CompareGreaterEqual, nil - case configs.LessThan: - return libseccomp.CompareLess, nil - case configs.LessThanOrEqualTo: - return libseccomp.CompareLessOrEqual, nil - case configs.MaskEqualTo: - return libseccomp.CompareMaskedEqual, nil - default: - return libseccomp.CompareInvalid, errors.New("invalid operator, cannot use in rule") - } -} - -// Convert Libcontainer Arg to Libseccomp ScmpCondition -func getCondition(arg *configs.Arg) (libseccomp.ScmpCondition, error) { - cond := libseccomp.ScmpCondition{} - - if arg == nil { - return cond, errors.New("cannot convert nil to syscall condition") - } - - op, err := getOperator(arg.Op) - if err != nil { - return cond, err - } - - return libseccomp.MakeCondition(arg.Index, op, arg.Value, arg.ValueTwo) -} - -// Add a rule to match a single syscall -func matchCall(filter *libseccomp.ScmpFilter, call *configs.Syscall, defAct libseccomp.ScmpAction) error { - if call == nil || filter == nil { - return errors.New("cannot use nil as syscall to block") - } - - if len(call.Name) == 0 { - return errors.New("empty string is not a valid syscall") - } - - // Convert the call's action to the libseccomp equivalent - callAct, err := getAction(call.Action, call.ErrnoRet) - if err != nil { - return fmt.Errorf("action in seccomp profile is invalid: %w", err) - } - if callAct == defAct { - // This rule is redundant, silently skip it - // to avoid error from AddRule. - return nil - } - - // If we can't resolve the syscall, assume it is not supported - // by this kernel. Warn about it, don't error out. - callNum, err := libseccomp.GetSyscallFromName(call.Name) - if err != nil { - logrus.Debugf("unknown seccomp syscall %q ignored", call.Name) - return nil - } - - // Unconditional match - just add the rule - if len(call.Args) == 0 { - if err := filter.AddRule(callNum, callAct); err != nil { - return fmt.Errorf("error adding seccomp filter rule for syscall %s: %w", call.Name, err) - } - } else { - // If two or more arguments have the same condition, - // Revert to old behavior, adding each condition as a separate rule - argCounts := make([]uint, syscallMaxArguments) - conditions := []libseccomp.ScmpCondition{} - - for _, cond := range call.Args { - newCond, err := getCondition(cond) - if err != nil { - return fmt.Errorf("error creating seccomp syscall condition for syscall %s: %w", call.Name, err) - } - - argCounts[cond.Index] += 1 - - conditions = append(conditions, newCond) - } - - hasMultipleArgs := false - for _, count := range argCounts { - if count > 1 { - hasMultipleArgs = true - break - } - } - - if hasMultipleArgs { - // Revert to old behavior - // Add each condition attached to a separate rule - for _, cond := range conditions { - condArr := []libseccomp.ScmpCondition{cond} - - if err := filter.AddRuleConditional(callNum, callAct, condArr); err != nil { - return fmt.Errorf("error adding seccomp rule for syscall %s: %w", call.Name, err) - } - } - } else { - // No conditions share same argument - // Use new, proper behavior - if err := filter.AddRuleConditional(callNum, callAct, conditions); err != nil { - return fmt.Errorf("error adding seccomp rule for syscall %s: %w", call.Name, err) - } - } - } - - return nil -} - -// Version returns major, minor, and micro. -func Version() (uint, uint, uint) { - return libseccomp.GetLibraryVersion() -} - -// Enabled is true if seccomp support is compiled in. -const Enabled = true diff --git a/vendor/github.com/opencontainers/runc/libcontainer/seccomp/seccomp_unsupported.go b/vendor/github.com/opencontainers/runc/libcontainer/seccomp/seccomp_unsupported.go deleted file mode 100644 index be2b324e057..00000000000 --- a/vendor/github.com/opencontainers/runc/libcontainer/seccomp/seccomp_unsupported.go +++ /dev/null @@ -1,28 +0,0 @@ -//go:build !linux || !cgo || !seccomp -// +build !linux !cgo !seccomp - -package seccomp - -import ( - "errors" - - "github.com/opencontainers/runc/libcontainer/configs" -) - -var ErrSeccompNotEnabled = errors.New("seccomp: config provided but seccomp not supported") - -// InitSeccomp does nothing because seccomp is not supported. -func InitSeccomp(config *configs.Seccomp) (int, error) { - if config != nil { - return -1, ErrSeccompNotEnabled - } - return -1, nil -} - -// Version returns major, minor, and micro. -func Version() (uint, uint, uint) { - return 0, 0, 0 -} - -// Enabled is true if seccomp support is compiled in. -const Enabled = false diff --git a/vendor/github.com/opencontainers/runc/libcontainer/setns_init_linux.go b/vendor/github.com/opencontainers/runc/libcontainer/setns_init_linux.go deleted file mode 100644 index bb358901c34..00000000000 --- a/vendor/github.com/opencontainers/runc/libcontainer/setns_init_linux.go +++ /dev/null @@ -1,149 +0,0 @@ -package libcontainer - -import ( - "errors" - "fmt" - "os" - "os/exec" - "strconv" - - "github.com/opencontainers/selinux/go-selinux" - "github.com/sirupsen/logrus" - "golang.org/x/sys/unix" - - "github.com/opencontainers/runc/libcontainer/apparmor" - "github.com/opencontainers/runc/libcontainer/keys" - "github.com/opencontainers/runc/libcontainer/seccomp" - "github.com/opencontainers/runc/libcontainer/system" - "github.com/opencontainers/runc/libcontainer/utils" -) - -// linuxSetnsInit performs the container's initialization for running a new process -// inside an existing container. -type linuxSetnsInit struct { - pipe *os.File - consoleSocket *os.File - config *initConfig - logFd int -} - -func (l *linuxSetnsInit) getSessionRingName() string { - return "_ses." + l.config.ContainerId -} - -func (l *linuxSetnsInit) Init() error { - if !l.config.Config.NoNewKeyring { - if err := selinux.SetKeyLabel(l.config.ProcessLabel); err != nil { - return err - } - defer selinux.SetKeyLabel("") //nolint: errcheck - // Do not inherit the parent's session keyring. - if _, err := keys.JoinSessionKeyring(l.getSessionRingName()); err != nil { - // Same justification as in standart_init_linux.go as to why we - // don't bail on ENOSYS. - // - // TODO(cyphar): And we should have logging here too. - if !errors.Is(err, unix.ENOSYS) { - return fmt.Errorf("unable to join session keyring: %w", err) - } - } - } - - if l.config.CreateConsole { - if err := setupConsole(l.consoleSocket, l.config, false); err != nil { - return err - } - if err := system.Setctty(); err != nil { - return err - } - } - if l.config.NoNewPrivileges { - if err := unix.Prctl(unix.PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0); err != nil { - return err - } - } - - // Tell our parent that we're ready to exec. This must be done before the - // Seccomp rules have been applied, because we need to be able to read and - // write to a socket. - if err := syncParentReady(l.pipe); err != nil { - return fmt.Errorf("sync ready: %w", err) - } - - if err := selinux.SetExecLabel(l.config.ProcessLabel); err != nil { - return err - } - defer selinux.SetExecLabel("") //nolint: errcheck - // Without NoNewPrivileges seccomp is a privileged operation, so we need to - // do this before dropping capabilities; otherwise do it as late as possible - // just before execve so as few syscalls take place after it as possible. - if l.config.Config.Seccomp != nil && !l.config.NoNewPrivileges { - seccompFd, err := seccomp.InitSeccomp(l.config.Config.Seccomp) - if err != nil { - return err - } - - if err := syncParentSeccomp(l.pipe, seccompFd); err != nil { - return err - } - } - if err := finalizeNamespace(l.config); err != nil { - return err - } - if err := apparmor.ApplyProfile(l.config.AppArmorProfile); err != nil { - return err - } - - // Check for the arg before waiting to make sure it exists and it is - // returned as a create time error. - name, err := exec.LookPath(l.config.Args[0]) - if err != nil { - return err - } - // exec.LookPath in Go < 1.20 might return no error for an executable - // residing on a file system mounted with noexec flag, so perform this - // extra check now while we can still return a proper error. - // TODO: remove this once go < 1.20 is not supported. - if err := eaccess(name); err != nil { - return &os.PathError{Op: "eaccess", Path: name, Err: err} - } - - // Set seccomp as close to execve as possible, so as few syscalls take - // place afterward (reducing the amount of syscalls that users need to - // enable in their seccomp profiles). - if l.config.Config.Seccomp != nil && l.config.NoNewPrivileges { - seccompFd, err := seccomp.InitSeccomp(l.config.Config.Seccomp) - if err != nil { - return fmt.Errorf("unable to init seccomp: %w", err) - } - - if err := syncParentSeccomp(l.pipe, seccompFd); err != nil { - return err - } - } - logrus.Debugf("setns_init: about to exec") - // Close the log pipe fd so the parent's ForwardLogs can exit. - if err := unix.Close(l.logFd); err != nil { - return &os.PathError{Op: "close log pipe", Path: "fd " + strconv.Itoa(l.logFd), Err: err} - } - - // Close all file descriptors we are not passing to the container. This is - // necessary because the execve target could use internal runc fds as the - // execve path, potentially giving access to binary files from the host - // (which can then be opened by container processes, leading to container - // escapes). Note that because this operation will close any open file - // descriptors that are referenced by (*os.File) handles from underneath - // the Go runtime, we must not do any file operations after this point - // (otherwise the (*os.File) finaliser could close the wrong file). See - // CVE-2024-21626 for more information as to why this protection is - // necessary. - // - // This is not needed for runc-dmz, because the extra execve(2) step means - // that all O_CLOEXEC file descriptors have already been closed and thus - // the second execve(2) from runc-dmz cannot access internal file - // descriptors from runc. - if err := utils.UnsafeCloseFrom(l.config.PassedFilesCount + 3); err != nil { - return err - } - return system.Exec(name, l.config.Args[0:], os.Environ()) -} diff --git a/vendor/github.com/opencontainers/runc/libcontainer/standard_init_linux.go b/vendor/github.com/opencontainers/runc/libcontainer/standard_init_linux.go deleted file mode 100644 index d9a6a224c5c..00000000000 --- a/vendor/github.com/opencontainers/runc/libcontainer/standard_init_linux.go +++ /dev/null @@ -1,282 +0,0 @@ -package libcontainer - -import ( - "errors" - "fmt" - "os" - "os/exec" - "strconv" - - "github.com/opencontainers/runtime-spec/specs-go" - "github.com/opencontainers/selinux/go-selinux" - "github.com/sirupsen/logrus" - "golang.org/x/sys/unix" - - "github.com/opencontainers/runc/libcontainer/apparmor" - "github.com/opencontainers/runc/libcontainer/configs" - "github.com/opencontainers/runc/libcontainer/keys" - "github.com/opencontainers/runc/libcontainer/seccomp" - "github.com/opencontainers/runc/libcontainer/system" - "github.com/opencontainers/runc/libcontainer/utils" -) - -type linuxStandardInit struct { - pipe *os.File - consoleSocket *os.File - parentPid int - fifoFd int - logFd int - mountFds []int - config *initConfig -} - -func (l *linuxStandardInit) getSessionRingParams() (string, uint32, uint32) { - var newperms uint32 - - if l.config.Config.Namespaces.Contains(configs.NEWUSER) { - // With user ns we need 'other' search permissions. - newperms = 0x8 - } else { - // Without user ns we need 'UID' search permissions. - newperms = 0x80000 - } - - // Create a unique per session container name that we can join in setns; - // However, other containers can also join it. - return "_ses." + l.config.ContainerId, 0xffffffff, newperms -} - -func (l *linuxStandardInit) Init() error { - if !l.config.Config.NoNewKeyring { - if err := selinux.SetKeyLabel(l.config.ProcessLabel); err != nil { - return err - } - defer selinux.SetKeyLabel("") //nolint: errcheck - ringname, keepperms, newperms := l.getSessionRingParams() - - // Do not inherit the parent's session keyring. - if sessKeyId, err := keys.JoinSessionKeyring(ringname); err != nil { - // If keyrings aren't supported then it is likely we are on an - // older kernel (or inside an LXC container). While we could bail, - // the security feature we are using here is best-effort (it only - // really provides marginal protection since VFS credentials are - // the only significant protection of keyrings). - // - // TODO(cyphar): Log this so people know what's going on, once we - // have proper logging in 'runc init'. - if !errors.Is(err, unix.ENOSYS) { - return fmt.Errorf("unable to join session keyring: %w", err) - } - } else { - // Make session keyring searchable. If we've gotten this far we - // bail on any error -- we don't want to have a keyring with bad - // permissions. - if err := keys.ModKeyringPerm(sessKeyId, keepperms, newperms); err != nil { - return fmt.Errorf("unable to mod keyring permissions: %w", err) - } - } - } - - if err := setupNetwork(l.config); err != nil { - return err - } - if err := setupRoute(l.config.Config); err != nil { - return err - } - - // initialises the labeling system - selinux.GetEnabled() - - // We don't need the mountFds after prepareRootfs() nor if it fails. - err := prepareRootfs(l.pipe, l.config, l.mountFds) - for _, m := range l.mountFds { - if m == -1 { - continue - } - - if err := unix.Close(m); err != nil { - return fmt.Errorf("Unable to close mountFds fds: %w", err) - } - } - - if err != nil { - return err - } - - // Set up the console. This has to be done *before* we finalize the rootfs, - // but *after* we've given the user the chance to set up all of the mounts - // they wanted. - if l.config.CreateConsole { - if err := setupConsole(l.consoleSocket, l.config, true); err != nil { - return err - } - if err := system.Setctty(); err != nil { - return &os.SyscallError{Syscall: "ioctl(setctty)", Err: err} - } - } - - // Finish the rootfs setup. - if l.config.Config.Namespaces.Contains(configs.NEWNS) { - if err := finalizeRootfs(l.config.Config); err != nil { - return err - } - } - - if hostname := l.config.Config.Hostname; hostname != "" { - if err := unix.Sethostname([]byte(hostname)); err != nil { - return &os.SyscallError{Syscall: "sethostname", Err: err} - } - } - if err := apparmor.ApplyProfile(l.config.AppArmorProfile); err != nil { - return fmt.Errorf("unable to apply apparmor profile: %w", err) - } - - for key, value := range l.config.Config.Sysctl { - if err := writeSystemProperty(key, value); err != nil { - return err - } - } - for _, path := range l.config.Config.ReadonlyPaths { - if err := readonlyPath(path); err != nil { - return fmt.Errorf("can't make %q read-only: %w", path, err) - } - } - for _, path := range l.config.Config.MaskPaths { - if err := maskPath(path, l.config.Config.MountLabel); err != nil { - return fmt.Errorf("can't mask path %s: %w", path, err) - } - } - pdeath, err := system.GetParentDeathSignal() - if err != nil { - return fmt.Errorf("can't get pdeath signal: %w", err) - } - if l.config.NoNewPrivileges { - if err := unix.Prctl(unix.PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0); err != nil { - return &os.SyscallError{Syscall: "prctl(SET_NO_NEW_PRIVS)", Err: err} - } - } - - // Tell our parent that we're ready to exec. This must be done before the - // Seccomp rules have been applied, because we need to be able to read and - // write to a socket. - if err := syncParentReady(l.pipe); err != nil { - return fmt.Errorf("sync ready: %w", err) - } - if err := selinux.SetExecLabel(l.config.ProcessLabel); err != nil { - return fmt.Errorf("can't set process label: %w", err) - } - defer selinux.SetExecLabel("") //nolint: errcheck - // Without NoNewPrivileges seccomp is a privileged operation, so we need to - // do this before dropping capabilities; otherwise do it as late as possible - // just before execve so as few syscalls take place after it as possible. - if l.config.Config.Seccomp != nil && !l.config.NoNewPrivileges { - seccompFd, err := seccomp.InitSeccomp(l.config.Config.Seccomp) - if err != nil { - return err - } - - if err := syncParentSeccomp(l.pipe, seccompFd); err != nil { - return err - } - } - if err := finalizeNamespace(l.config); err != nil { - return err - } - // finalizeNamespace can change user/group which clears the parent death - // signal, so we restore it here. - if err := pdeath.Restore(); err != nil { - return fmt.Errorf("can't restore pdeath signal: %w", err) - } - // Compare the parent from the initial start of the init process and make - // sure that it did not change. if the parent changes that means it died - // and we were reparented to something else so we should just kill ourself - // and not cause problems for someone else. - if unix.Getppid() != l.parentPid { - return unix.Kill(unix.Getpid(), unix.SIGKILL) - } - // Check for the arg before waiting to make sure it exists and it is - // returned as a create time error. - name, err := exec.LookPath(l.config.Args[0]) - if err != nil { - return err - } - // exec.LookPath in Go < 1.20 might return no error for an executable - // residing on a file system mounted with noexec flag, so perform this - // extra check now while we can still return a proper error. - // TODO: remove this once go < 1.20 is not supported. - if err := eaccess(name); err != nil { - return &os.PathError{Op: "eaccess", Path: name, Err: err} - } - - // Set seccomp as close to execve as possible, so as few syscalls take - // place afterward (reducing the amount of syscalls that users need to - // enable in their seccomp profiles). However, this needs to be done - // before closing the pipe since we need it to pass the seccompFd to - // the parent. - if l.config.Config.Seccomp != nil && l.config.NoNewPrivileges { - seccompFd, err := seccomp.InitSeccomp(l.config.Config.Seccomp) - if err != nil { - return fmt.Errorf("unable to init seccomp: %w", err) - } - - if err := syncParentSeccomp(l.pipe, seccompFd); err != nil { - return err - } - } - // Close the pipe to signal that we have completed our init. - logrus.Debugf("init: closing the pipe to signal completion") - _ = l.pipe.Close() - - // Close the log pipe fd so the parent's ForwardLogs can exit. - if err := unix.Close(l.logFd); err != nil { - return &os.PathError{Op: "close log pipe", Path: "fd " + strconv.Itoa(l.logFd), Err: err} - } - - // Wait for the FIFO to be opened on the other side before exec-ing the - // user process. We open it through /proc/self/fd/$fd, because the fd that - // was given to us was an O_PATH fd to the fifo itself. Linux allows us to - // re-open an O_PATH fd through /proc. - fifoPath := "/proc/self/fd/" + strconv.Itoa(l.fifoFd) - fd, err := unix.Open(fifoPath, unix.O_WRONLY|unix.O_CLOEXEC, 0) - if err != nil { - return &os.PathError{Op: "open exec fifo", Path: fifoPath, Err: err} - } - if _, err := unix.Write(fd, []byte("0")); err != nil { - return &os.PathError{Op: "write exec fifo", Path: fifoPath, Err: err} - } - - // Close the O_PATH fifofd fd before exec because the kernel resets - // dumpable in the wrong order. This has been fixed in newer kernels, but - // we keep this to ensure CVE-2016-9962 doesn't re-emerge on older kernels. - // N.B. the core issue itself (passing dirfds to the host filesystem) has - // since been resolved. - // https://github.com/torvalds/linux/blob/v4.9/fs/exec.c#L1290-L1318 - _ = unix.Close(l.fifoFd) - - s := l.config.SpecState - s.Pid = unix.Getpid() - s.Status = specs.StateCreated - if err := l.config.Config.Hooks[configs.StartContainer].RunHooks(s); err != nil { - return err - } - - // Close all file descriptors we are not passing to the container. This is - // necessary because the execve target could use internal runc fds as the - // execve path, potentially giving access to binary files from the host - // (which can then be opened by container processes, leading to container - // escapes). Note that because this operation will close any open file - // descriptors that are referenced by (*os.File) handles from underneath - // the Go runtime, we must not do any file operations after this point - // (otherwise the (*os.File) finaliser could close the wrong file). See - // CVE-2024-21626 for more information as to why this protection is - // necessary. - // - // This is not needed for runc-dmz, because the extra execve(2) step means - // that all O_CLOEXEC file descriptors have already been closed and thus - // the second execve(2) from runc-dmz cannot access internal file - // descriptors from runc. - if err := utils.UnsafeCloseFrom(l.config.PassedFilesCount + 3); err != nil { - return err - } - return system.Exec(name, l.config.Args[0:], os.Environ()) -} diff --git a/vendor/github.com/opencontainers/runc/libcontainer/state_linux.go b/vendor/github.com/opencontainers/runc/libcontainer/state_linux.go deleted file mode 100644 index aa6259b157d..00000000000 --- a/vendor/github.com/opencontainers/runc/libcontainer/state_linux.go +++ /dev/null @@ -1,243 +0,0 @@ -package libcontainer - -import ( - "fmt" - "os" - "path/filepath" - - "github.com/opencontainers/runc/libcontainer/configs" - "github.com/opencontainers/runtime-spec/specs-go" - "github.com/sirupsen/logrus" - "golang.org/x/sys/unix" -) - -func newStateTransitionError(from, to containerState) error { - return &stateTransitionError{ - From: from.status().String(), - To: to.status().String(), - } -} - -// stateTransitionError is returned when an invalid state transition happens from one -// state to another. -type stateTransitionError struct { - From string - To string -} - -func (s *stateTransitionError) Error() string { - return fmt.Sprintf("invalid state transition from %s to %s", s.From, s.To) -} - -type containerState interface { - transition(containerState) error - destroy() error - status() Status -} - -func destroy(c *linuxContainer) error { - if !c.config.Namespaces.Contains(configs.NEWPID) || - c.config.Namespaces.PathOf(configs.NEWPID) != "" { - if err := signalAllProcesses(c.cgroupManager, unix.SIGKILL); err != nil { - logrus.Warn(err) - } - } - err := c.cgroupManager.Destroy() - if c.intelRdtManager != nil { - if ierr := c.intelRdtManager.Destroy(); err == nil { - err = ierr - } - } - if rerr := os.RemoveAll(c.root); err == nil { - err = rerr - } - c.initProcess = nil - if herr := runPoststopHooks(c); err == nil { - err = herr - } - c.state = &stoppedState{c: c} - return err -} - -func runPoststopHooks(c *linuxContainer) error { - hooks := c.config.Hooks - if hooks == nil { - return nil - } - - s, err := c.currentOCIState() - if err != nil { - return err - } - s.Status = specs.StateStopped - - if err := hooks[configs.Poststop].RunHooks(s); err != nil { - return err - } - - return nil -} - -// stoppedState represents a container is a stopped/destroyed state. -type stoppedState struct { - c *linuxContainer -} - -func (b *stoppedState) status() Status { - return Stopped -} - -func (b *stoppedState) transition(s containerState) error { - switch s.(type) { - case *runningState, *restoredState: - b.c.state = s - return nil - case *stoppedState: - return nil - } - return newStateTransitionError(b, s) -} - -func (b *stoppedState) destroy() error { - return destroy(b.c) -} - -// runningState represents a container that is currently running. -type runningState struct { - c *linuxContainer -} - -func (r *runningState) status() Status { - return Running -} - -func (r *runningState) transition(s containerState) error { - switch s.(type) { - case *stoppedState: - if r.c.runType() == Running { - return ErrRunning - } - r.c.state = s - return nil - case *pausedState: - r.c.state = s - return nil - case *runningState: - return nil - } - return newStateTransitionError(r, s) -} - -func (r *runningState) destroy() error { - if r.c.runType() == Running { - return ErrRunning - } - return destroy(r.c) -} - -type createdState struct { - c *linuxContainer -} - -func (i *createdState) status() Status { - return Created -} - -func (i *createdState) transition(s containerState) error { - switch s.(type) { - case *runningState, *pausedState, *stoppedState: - i.c.state = s - return nil - case *createdState: - return nil - } - return newStateTransitionError(i, s) -} - -func (i *createdState) destroy() error { - _ = i.c.initProcess.signal(unix.SIGKILL) - return destroy(i.c) -} - -// pausedState represents a container that is currently pause. It cannot be destroyed in a -// paused state and must transition back to running first. -type pausedState struct { - c *linuxContainer -} - -func (p *pausedState) status() Status { - return Paused -} - -func (p *pausedState) transition(s containerState) error { - switch s.(type) { - case *runningState, *stoppedState: - p.c.state = s - return nil - case *pausedState: - return nil - } - return newStateTransitionError(p, s) -} - -func (p *pausedState) destroy() error { - t := p.c.runType() - if t != Running && t != Created { - if err := p.c.cgroupManager.Freeze(configs.Thawed); err != nil { - return err - } - return destroy(p.c) - } - return ErrPaused -} - -// restoredState is the same as the running state but also has associated checkpoint -// information that maybe need destroyed when the container is stopped and destroy is called. -type restoredState struct { - imageDir string - c *linuxContainer -} - -func (r *restoredState) status() Status { - return Running -} - -func (r *restoredState) transition(s containerState) error { - switch s.(type) { - case *stoppedState, *runningState: - return nil - } - return newStateTransitionError(r, s) -} - -func (r *restoredState) destroy() error { - if _, err := os.Stat(filepath.Join(r.c.root, "checkpoint")); err != nil { - if !os.IsNotExist(err) { - return err - } - } - return destroy(r.c) -} - -// loadedState is used whenever a container is restored, loaded, or setting additional -// processes inside and it should not be destroyed when it is exiting. -type loadedState struct { - c *linuxContainer - s Status -} - -func (n *loadedState) status() Status { - return n.s -} - -func (n *loadedState) transition(s containerState) error { - n.c.state = s - return nil -} - -func (n *loadedState) destroy() error { - if err := n.c.refreshState(); err != nil { - return err - } - return n.c.state.destroy() -} diff --git a/vendor/github.com/opencontainers/runc/libcontainer/stats_linux.go b/vendor/github.com/opencontainers/runc/libcontainer/stats_linux.go deleted file mode 100644 index fff9dd37af3..00000000000 --- a/vendor/github.com/opencontainers/runc/libcontainer/stats_linux.go +++ /dev/null @@ -1,13 +0,0 @@ -package libcontainer - -import ( - "github.com/opencontainers/runc/libcontainer/cgroups" - "github.com/opencontainers/runc/libcontainer/intelrdt" - "github.com/opencontainers/runc/types" -) - -type Stats struct { - Interfaces []*types.NetworkInterface - CgroupStats *cgroups.Stats - IntelRdtStats *intelrdt.Stats -} diff --git a/vendor/github.com/opencontainers/runc/libcontainer/sync.go b/vendor/github.com/opencontainers/runc/libcontainer/sync.go deleted file mode 100644 index 25dc2863071..00000000000 --- a/vendor/github.com/opencontainers/runc/libcontainer/sync.go +++ /dev/null @@ -1,126 +0,0 @@ -package libcontainer - -import ( - "encoding/json" - "errors" - "fmt" - "io" - - "github.com/opencontainers/runc/libcontainer/utils" -) - -type syncType string - -// Constants that are used for synchronisation between the parent and child -// during container setup. They come in pairs (with procError being a generic -// response which is followed by an &initError). -// -// [ child ] <-> [ parent ] -// -// procHooks --> [run hooks] -// <-- procResume -// -// procReady --> [final setup] -// <-- procRun -// -// procSeccomp --> [pick up seccomp fd with pidfd_getfd()] -// <-- procSeccompDone -const ( - procError syncType = "procError" - procReady syncType = "procReady" - procRun syncType = "procRun" - procHooks syncType = "procHooks" - procResume syncType = "procResume" - procSeccomp syncType = "procSeccomp" - procSeccompDone syncType = "procSeccompDone" -) - -type syncT struct { - Type syncType `json:"type"` - Fd int `json:"fd"` -} - -// initError is used to wrap errors for passing them via JSON, -// as encoding/json can't unmarshal into error type. -type initError struct { - Message string `json:"message,omitempty"` -} - -func (i initError) Error() string { - return i.Message -} - -// writeSync is used to write to a synchronisation pipe. An error is returned -// if there was a problem writing the payload. -func writeSync(pipe io.Writer, sync syncType) error { - return writeSyncWithFd(pipe, sync, -1) -} - -// writeSyncWithFd is used to write to a synchronisation pipe. An error is -// returned if there was a problem writing the payload. -func writeSyncWithFd(pipe io.Writer, sync syncType, fd int) error { - if err := utils.WriteJSON(pipe, syncT{sync, fd}); err != nil { - return fmt.Errorf("writing syncT %q: %w", string(sync), err) - } - return nil -} - -// readSync is used to read from a synchronisation pipe. An error is returned -// if we got an initError, the pipe was closed, or we got an unexpected flag. -func readSync(pipe io.Reader, expected syncType) error { - var procSync syncT - if err := json.NewDecoder(pipe).Decode(&procSync); err != nil { - if errors.Is(err, io.EOF) { - return errors.New("parent closed synchronisation channel") - } - return fmt.Errorf("failed reading error from parent: %w", err) - } - - if procSync.Type == procError { - var ierr initError - - if err := json.NewDecoder(pipe).Decode(&ierr); err != nil { - return fmt.Errorf("failed reading error from parent: %w", err) - } - - return &ierr - } - - if procSync.Type != expected { - return errors.New("invalid synchronisation flag from parent") - } - return nil -} - -// parseSync runs the given callback function on each syncT received from the -// child. It will return once io.EOF is returned from the given pipe. -func parseSync(pipe io.Reader, fn func(*syncT) error) error { - dec := json.NewDecoder(pipe) - for { - var sync syncT - if err := dec.Decode(&sync); err != nil { - if errors.Is(err, io.EOF) { - break - } - return err - } - - // We handle this case outside fn for cleanliness reasons. - var ierr *initError - if sync.Type == procError { - if err := dec.Decode(&ierr); err != nil && !errors.Is(err, io.EOF) { - return fmt.Errorf("error decoding proc error from init: %w", err) - } - if ierr != nil { - return ierr - } - // Programmer error. - panic("No error following JSON procError payload.") - } - - if err := fn(&sync); err != nil { - return err - } - } - return nil -} diff --git a/vendor/github.com/opencontainers/runc/types/events.go b/vendor/github.com/opencontainers/runc/types/events.go deleted file mode 100644 index 81bde829da5..00000000000 --- a/vendor/github.com/opencontainers/runc/types/events.go +++ /dev/null @@ -1,155 +0,0 @@ -package types - -import "github.com/opencontainers/runc/libcontainer/intelrdt" - -// Event struct for encoding the event data to json. -type Event struct { - Type string `json:"type"` - ID string `json:"id"` - Data interface{} `json:"data,omitempty"` -} - -// stats is the runc specific stats structure for stability when encoding and decoding stats. -type Stats struct { - CPU Cpu `json:"cpu"` - CPUSet CPUSet `json:"cpuset"` - Memory Memory `json:"memory"` - Pids Pids `json:"pids"` - Blkio Blkio `json:"blkio"` - Hugetlb map[string]Hugetlb `json:"hugetlb"` - IntelRdt IntelRdt `json:"intel_rdt"` - NetworkInterfaces []*NetworkInterface `json:"network_interfaces"` -} - -type Hugetlb struct { - Usage uint64 `json:"usage,omitempty"` - Max uint64 `json:"max,omitempty"` - Failcnt uint64 `json:"failcnt"` -} - -type BlkioEntry struct { - Major uint64 `json:"major,omitempty"` - Minor uint64 `json:"minor,omitempty"` - Op string `json:"op,omitempty"` - Value uint64 `json:"value,omitempty"` -} - -type Blkio struct { - IoServiceBytesRecursive []BlkioEntry `json:"ioServiceBytesRecursive,omitempty"` - IoServicedRecursive []BlkioEntry `json:"ioServicedRecursive,omitempty"` - IoQueuedRecursive []BlkioEntry `json:"ioQueueRecursive,omitempty"` - IoServiceTimeRecursive []BlkioEntry `json:"ioServiceTimeRecursive,omitempty"` - IoWaitTimeRecursive []BlkioEntry `json:"ioWaitTimeRecursive,omitempty"` - IoMergedRecursive []BlkioEntry `json:"ioMergedRecursive,omitempty"` - IoTimeRecursive []BlkioEntry `json:"ioTimeRecursive,omitempty"` - SectorsRecursive []BlkioEntry `json:"sectorsRecursive,omitempty"` -} - -type Pids struct { - Current uint64 `json:"current,omitempty"` - Limit uint64 `json:"limit,omitempty"` -} - -type Throttling struct { - Periods uint64 `json:"periods,omitempty"` - ThrottledPeriods uint64 `json:"throttledPeriods,omitempty"` - ThrottledTime uint64 `json:"throttledTime,omitempty"` -} - -type CpuUsage struct { - // Units: nanoseconds. - Total uint64 `json:"total,omitempty"` - Percpu []uint64 `json:"percpu,omitempty"` - PercpuKernel []uint64 `json:"percpu_kernel,omitempty"` - PercpuUser []uint64 `json:"percpu_user,omitempty"` - Kernel uint64 `json:"kernel"` - User uint64 `json:"user"` -} - -type Cpu struct { - Usage CpuUsage `json:"usage,omitempty"` - Throttling Throttling `json:"throttling,omitempty"` -} - -type CPUSet struct { - CPUs []uint16 `json:"cpus,omitempty"` - CPUExclusive uint64 `json:"cpu_exclusive"` - Mems []uint16 `json:"mems,omitempty"` - MemHardwall uint64 `json:"mem_hardwall"` - MemExclusive uint64 `json:"mem_exclusive"` - MemoryMigrate uint64 `json:"memory_migrate"` - MemorySpreadPage uint64 `json:"memory_spread_page"` - MemorySpreadSlab uint64 `json:"memory_spread_slab"` - MemoryPressure uint64 `json:"memory_pressure"` - SchedLoadBalance uint64 `json:"sched_load_balance"` - SchedRelaxDomainLevel int64 `json:"sched_relax_domain_level"` -} - -type MemoryEntry struct { - Limit uint64 `json:"limit"` - Usage uint64 `json:"usage,omitempty"` - Max uint64 `json:"max,omitempty"` - Failcnt uint64 `json:"failcnt"` -} - -type Memory struct { - Cache uint64 `json:"cache,omitempty"` - Usage MemoryEntry `json:"usage,omitempty"` - Swap MemoryEntry `json:"swap,omitempty"` - Kernel MemoryEntry `json:"kernel,omitempty"` - KernelTCP MemoryEntry `json:"kernelTCP,omitempty"` - Raw map[string]uint64 `json:"raw,omitempty"` -} - -type L3CacheInfo struct { - CbmMask string `json:"cbm_mask,omitempty"` - MinCbmBits uint64 `json:"min_cbm_bits,omitempty"` - NumClosids uint64 `json:"num_closids,omitempty"` -} - -type MemBwInfo struct { - BandwidthGran uint64 `json:"bandwidth_gran,omitempty"` - DelayLinear uint64 `json:"delay_linear,omitempty"` - MinBandwidth uint64 `json:"min_bandwidth,omitempty"` - NumClosids uint64 `json:"num_closids,omitempty"` -} - -type IntelRdt struct { - // The read-only L3 cache information - L3CacheInfo *L3CacheInfo `json:"l3_cache_info,omitempty"` - - // The read-only L3 cache schema in root - L3CacheSchemaRoot string `json:"l3_cache_schema_root,omitempty"` - - // The L3 cache schema in 'container_id' group - L3CacheSchema string `json:"l3_cache_schema,omitempty"` - - // The read-only memory bandwidth information - MemBwInfo *MemBwInfo `json:"mem_bw_info,omitempty"` - - // The read-only memory bandwidth schema in root - MemBwSchemaRoot string `json:"mem_bw_schema_root,omitempty"` - - // The memory bandwidth schema in 'container_id' group - MemBwSchema string `json:"mem_bw_schema,omitempty"` - - // The memory bandwidth monitoring statistics from NUMA nodes in 'container_id' group - MBMStats *[]intelrdt.MBMNumaNodeStats `json:"mbm_stats,omitempty"` - - // The cache monitoring technology statistics from NUMA nodes in 'container_id' group - CMTStats *[]intelrdt.CMTNumaNodeStats `json:"cmt_stats,omitempty"` -} - -type NetworkInterface struct { - // Name is the name of the network interface. - Name string - - RxBytes uint64 - RxPackets uint64 - RxErrors uint64 - RxDropped uint64 - TxBytes uint64 - TxPackets uint64 - TxErrors uint64 - TxDropped uint64 -} diff --git a/vendor/github.com/seccomp/libseccomp-golang/.gitignore b/vendor/github.com/seccomp/libseccomp-golang/.gitignore deleted file mode 100644 index b4826968b89..00000000000 --- a/vendor/github.com/seccomp/libseccomp-golang/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -*~ -*.swp -*.orig -tags diff --git a/vendor/github.com/seccomp/libseccomp-golang/.golangci.yml b/vendor/github.com/seccomp/libseccomp-golang/.golangci.yml deleted file mode 100644 index 7df8aa19838..00000000000 --- a/vendor/github.com/seccomp/libseccomp-golang/.golangci.yml +++ /dev/null @@ -1,4 +0,0 @@ -# For documentation, see https://golangci-lint.run/usage/configuration/ -linters: - enable: - - gofumpt diff --git a/vendor/github.com/seccomp/libseccomp-golang/CHANGELOG b/vendor/github.com/seccomp/libseccomp-golang/CHANGELOG deleted file mode 100644 index 905a9b5cdc8..00000000000 --- a/vendor/github.com/seccomp/libseccomp-golang/CHANGELOG +++ /dev/null @@ -1,42 +0,0 @@ -libseccomp-golang: Releases -=============================================================================== -https://github.com/seccomp/libseccomp-golang - -* Version 0.10.0 - June 9, 2022 -- Minimum supported version of libseccomp bumped to v2.3.1 -- Add seccomp userspace notification API (ActNotify, filter.*Notif*) -- Add filter.{Get,Set}SSB (to support SCMP_FLTATR_CTL_SSB) -- Add filter.{Get,Set}Optimize (to support SCMP_FLTATR_CTL_OPTIMIZE) -- Add filter.{Get,Set}RawRC (to support SCMP_FLTATR_API_SYSRAWRC) -- Add ArchPARISC, ArchPARISC64, ArchRISCV64 -- Add ActKillProcess and ActKillThread; deprecate ActKill -- Add go module support -- Return ErrSyscallDoesNotExist when unable to resolve a syscall -- Fix some functions to check for both kernel level API and libseccomp version -- Fix MakeCondition to use sanitizeCompareOp -- Fix AddRule to handle EACCES (from libseccomp >= 2.5.0) -- Updated the main docs and converted to README.md -- Added CONTRIBUTING.md, SECURITY.md, and administrative docs under doc/admin -- Add GitHub action CI, enable more linters -- test: test against various libseccomp versions -- test: fix and simplify execInSubprocess -- test: fix APILevelIsSupported -- Refactor the Errno(-1 * retCode) pattern -- Refactor/unify libseccomp version / API level checks -- Code cleanups (linter, formatting, spelling fixes) -- Cleanup: use errors.New instead of fmt.Errorf where appropriate -- Cleanup: remove duplicated cgo stuff, redundant linux build tag - -* Version 0.9.1 - May 21, 2019 -- Minimum supported version of libseccomp bumped to v2.2.0 -- Use Libseccomp's `seccomp_version` API to retrieve library version -- Unconditionally set TSync attribute for filters, due to Go's heavily threaded nature -- Fix CVE-2017-18367 - Multiple syscall arguments were incorrectly combined with logical-OR, instead of logical-AND -- Fix a failure to build on Debian-based distributions due to CGo code -- Fix unit test failures on 32-bit architectures -- Improve several errors to be more verbose about their causes -- Add support for SCMP_ACT_LOG (with libseccomp versions 2.4.x and higher), permitting syscalls but logging their execution -- Add support for SCMP_FLTATR_CTL_LOG (with libseccomp versions 2.4.x and higher), logging not-allowed actions when they are denied - -* Version 0.9.0 - January 5, 2017 -- Initial tagged release diff --git a/vendor/github.com/seccomp/libseccomp-golang/CONTRIBUTING.md b/vendor/github.com/seccomp/libseccomp-golang/CONTRIBUTING.md deleted file mode 100644 index c2fc80d5af6..00000000000 --- a/vendor/github.com/seccomp/libseccomp-golang/CONTRIBUTING.md +++ /dev/null @@ -1,120 +0,0 @@ -How to Submit Patches to the libseccomp-golang Project -=============================================================================== -https://github.com/seccomp/libseccomp-golang - -This document is intended to act as a guide to help you contribute to the -libseccomp-golang project. It is not perfect, and there will always be -exceptions to the rules described here, but by following the instructions below -you should have a much easier time getting your work merged with the upstream -project. - -## Test Your Code Using Existing Tests - -A number of tests and lint related recipes are provided in the Makefile, if -you want to run the standard regression tests, you can execute the following: - - # make check - -In order to use it, the 'golangci-lint' tool is needed, which can be found at: - -* https://github.com/golangci/golangci-lint - -## Add New Tests for New Functionality - -Any submissions which add functionality, or significantly change the existing -code, should include additional tests to verify the proper operation of the -proposed changes. - -## Explain Your Work - -At the top of every patch you should include a description of the problem you -are trying to solve, how you solved it, and why you chose the solution you -implemented. If you are submitting a bug fix, it is also incredibly helpful -if you can describe/include a reproducer for the problem in the description as -well as instructions on how to test for the bug and verify that it has been -fixed. - -## Sign Your Work - -The sign-off is a simple line at the end of the patch description, which -certifies that you wrote it or otherwise have the right to pass it on as an -open-source patch. The "Developer's Certificate of Origin" pledge is taken -from the Linux Kernel and the rules are pretty simple: - - Developer's Certificate of Origin 1.1 - - By making a contribution to this project, I certify that: - - (a) The contribution was created in whole or in part by me and I - have the right to submit it under the open source license - indicated in the file; or - - (b) The contribution is based upon previous work that, to the best - of my knowledge, is covered under an appropriate open source - license and I have the right under that license to submit that - work with modifications, whether created in whole or in part - by me, under the same open source license (unless I am - permitted to submit under a different license), as indicated - in the file; or - - (c) The contribution was provided directly to me by some other - person who certified (a), (b) or (c) and I have not modified - it. - - (d) I understand and agree that this project and the contribution - are public and that a record of the contribution (including all - personal information I submit with it, including my sign-off) is - maintained indefinitely and may be redistributed consistent with - this project or the open source license(s) involved. - -... then you just add a line to the bottom of your patch description, with -your real name, saying: - - Signed-off-by: Random J Developer - -You can add this to your commit description in `git` with `git commit -s` - -## Post Your Patches Upstream - -The libseccomp project accepts both GitHub pull requests and patches sent via -the mailing list. GitHub pull requests are preferred. This sections below -explain how to contribute via either method. Please read each step and perform -all steps that apply to your chosen contribution method. - -### Submitting via Email - -Depending on how you decided to work with the libseccomp code base and what -tools you are using there are different ways to generate your patch(es). -However, regardless of what tools you use, you should always generate your -patches using the "unified" diff/patch format and the patches should always -apply to the libseccomp source tree using the following command from the top -directory of the libseccomp sources: - - # patch -p1 < changes.patch - -If you are not using git, stacked git (stgit), or some other tool which can -generate patch files for you automatically, you may find the following command -helpful in generating patches, where "libseccomp.orig/" is the unmodified -source code directory and "libseccomp/" is the source code directory with your -changes: - - # diff -purN libseccomp.orig/ libseccomp/ - -When in doubt please generate your patch and try applying it to an unmodified -copy of the libseccomp sources; if it fails for you, it will fail for the rest -of us. - -Finally, you will need to email your patches to the mailing list so they can -be reviewed and potentially merged into the main libseccomp repository. When -sending patches to the mailing list it is important to send your email in text -form, no HTML mail please, and ensure that your email client does not mangle -your patches. It should be possible to save your raw email to disk and apply -it directly to the libseccomp source code; if that fails then you likely have -a problem with your email client. When in doubt try a test first by sending -yourself an email with your patch and attempting to apply the emailed patch to -the libseccomp repository; if it fails for you, it will fail for the rest of -us trying to test your patch and include it in the main libseccomp repository. - -### Submitting via GitHub - -See [this guide](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/creating-a-pull-request) if you've never done this before. diff --git a/vendor/github.com/seccomp/libseccomp-golang/LICENSE b/vendor/github.com/seccomp/libseccomp-golang/LICENSE deleted file mode 100644 index 81cf60de29e..00000000000 --- a/vendor/github.com/seccomp/libseccomp-golang/LICENSE +++ /dev/null @@ -1,22 +0,0 @@ -Copyright (c) 2015 Matthew Heon -Copyright (c) 2015 Paul Moore -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: -- Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/seccomp/libseccomp-golang/Makefile b/vendor/github.com/seccomp/libseccomp-golang/Makefile deleted file mode 100644 index 530f5b4adbc..00000000000 --- a/vendor/github.com/seccomp/libseccomp-golang/Makefile +++ /dev/null @@ -1,31 +0,0 @@ -# libseccomp-golang - -.PHONY: all check check-build check-syntax fix-syntax vet test lint - -all: check-build - -check: lint test - -check-build: - go build - -check-syntax: - gofmt -d . - -fix-syntax: - gofmt -w . - -vet: - go vet -v ./... - -# Previous bugs have made the tests freeze until the timeout. Golang default -# timeout for tests is 10 minutes, which is too long, considering current tests -# can be executed in less than 1 second. Reduce the timeout, so problems can -# be noticed earlier in the CI. -TEST_TIMEOUT=10s - -test: - go test -v -timeout $(TEST_TIMEOUT) - -lint: - golangci-lint run . diff --git a/vendor/github.com/seccomp/libseccomp-golang/README.md b/vendor/github.com/seccomp/libseccomp-golang/README.md deleted file mode 100644 index 312135ee59e..00000000000 --- a/vendor/github.com/seccomp/libseccomp-golang/README.md +++ /dev/null @@ -1,59 +0,0 @@ -![libseccomp Golang Bindings](https://github.com/seccomp/libseccomp-artwork/blob/main/logo/libseccomp-color_text.png) -=============================================================================== -https://github.com/seccomp/libseccomp-golang - -[![Go Reference](https://pkg.go.dev/badge/github.com/seccomp/libseccomp-golang.svg)](https://pkg.go.dev/github.com/seccomp/libseccomp-golang) -[![validate](https://github.com/seccomp/libseccomp-golang/actions/workflows/validate.yml/badge.svg)](https://github.com/seccomp/libseccomp-golang/actions/workflows/validate.yml) -[![test](https://github.com/seccomp/libseccomp-golang/actions/workflows/test.yml/badge.svg)](https://github.com/seccomp/libseccomp-golang/actions/workflows/test.yml) - -The libseccomp library provides an easy to use, platform independent, interface -to the Linux Kernel's syscall filtering mechanism. The libseccomp API is -designed to abstract away the underlying BPF based syscall filter language and -present a more conventional function-call based filtering interface that should -be familiar to, and easily adopted by, application developers. - -The libseccomp-golang library provides a Go based interface to the libseccomp -library. - -## Online Resources - -The library source repository currently lives on GitHub at the following URLs: - -* https://github.com/seccomp/libseccomp-golang -* https://github.com/seccomp/libseccomp - -Documentation for this package is also available at: - -* https://pkg.go.dev/github.com/seccomp/libseccomp-golang - -## Verifying Releases - -Starting with libseccomp-golang v0.10.0, the git tag corresponding to each -release should be signed by one of the libseccomp-golang maintainers. It is -recommended that before use you verify the release tags using the following -command: - - % git tag -v - -At present, only the following keys, specified via the fingerprints below, are -authorized to sign official libseccomp-golang release tags: - - Paul Moore - 7100 AADF AE6E 6E94 0D2E 0AD6 55E4 5A5A E8CA 7C8A - - Tom Hromatka - 47A6 8FCE 37C7 D702 4FD6 5E11 356C E62C 2B52 4099 - - Kir Kolyshkin - C242 8CD7 5720 FACD CF76 B6EA 17DE 5ECB 75A1 100E - -More information on GnuPG and git tag verification can be found at their -respective websites: https://git-scm.com/docs/git and https://gnupg.org. - -## Installing the package - - % go get github.com/seccomp/libseccomp-golang - -## Contributing - -See [CONTRIBUTING.md](CONTRIBUTING.md). diff --git a/vendor/github.com/seccomp/libseccomp-golang/SECURITY.md b/vendor/github.com/seccomp/libseccomp-golang/SECURITY.md deleted file mode 100644 index f645d4efec9..00000000000 --- a/vendor/github.com/seccomp/libseccomp-golang/SECURITY.md +++ /dev/null @@ -1,48 +0,0 @@ -The libseccomp-golang Security Vulnerability Handling Process -=============================================================================== -https://github.com/seccomp/libseccomp-golang - -This document document attempts to describe the processes through which -sensitive security relevant bugs can be responsibly disclosed to the -libseccomp-golang project and how the project maintainers should handle these -reports. Just like the other libseccomp-golang process documents, this -document should be treated as a guiding document and not a hard, unyielding set -of regulations; the bug reporters and project maintainers are encouraged to -work together to address the issues as best they can, in a manner which works -best for all parties involved. - -### Reporting Problems - -Problems with the libseccomp-golang library that are not suitable for immediate -public disclosure should be emailed to the current libseccomp-golang -maintainers, the list is below. We typically request at most a 90 day time -period to address the issue before it is made public, but we will make every -effort to address the issue as quickly as possible and shorten the disclosure -window. - -* Paul Moore, paul@paul-moore.com -* Tom Hromatka, tom.hromatka@oracle.com -* Kir Kolyshkin, kolyshkin@gmail.com - -### Resolving Sensitive Security Issues - -Upon disclosure of a bug, the maintainers should work together to investigate -the problem and decide on a solution. In order to prevent an early disclosure -of the problem, those working on the solution should do so privately and -outside of the traditional libseccomp-golang development practices. One -possible solution to this is to leverage the GitHub "Security" functionality to -create a private development fork that can be shared among the maintainers, and -optionally the reporter. A placeholder GitHub issue may be created, but -details should remain extremely limited until such time as the problem has been -fixed and responsibly disclosed. If a CVE, or other tag, has been assigned to -the problem, the GitHub issue title should include the vulnerability tag once -the problem has been disclosed. - -### Public Disclosure - -Whenever possible, responsible reporting and patching practices should be -followed, including notification to the linux-distros and oss-security mailing -lists. - -* https://oss-security.openwall.org/wiki/mailing-lists/distros -* https://oss-security.openwall.org/wiki/mailing-lists/oss-security diff --git a/vendor/github.com/seccomp/libseccomp-golang/seccomp.go b/vendor/github.com/seccomp/libseccomp-golang/seccomp.go deleted file mode 100644 index c23406754c6..00000000000 --- a/vendor/github.com/seccomp/libseccomp-golang/seccomp.go +++ /dev/null @@ -1,1188 +0,0 @@ -// Public API specification for libseccomp Go bindings -// Contains public API for the bindings - -// Package seccomp provides bindings for libseccomp, a library wrapping the Linux -// seccomp syscall. Seccomp enables an application to restrict system call use -// for itself and its children. -package seccomp - -import ( - "errors" - "fmt" - "os" - "runtime" - "strings" - "sync" - "syscall" - "unsafe" -) - -// #include -// #include -import "C" - -// Exported types - -// VersionError represents an error when either the system libseccomp version -// or the kernel version is too old to perform the operation requested. -type VersionError struct { - op string // operation that failed or would fail - major, minor, micro uint // minimally required libseccomp version - curAPI, minAPI uint // current and minimally required API versions -} - -func init() { - // This forces the cgo libseccomp to initialize its internal API support state, - // which is necessary on older versions of libseccomp in order to work - // correctly. - _, _ = getAPI() -} - -func (e VersionError) Error() string { - if e.minAPI != 0 { - return fmt.Sprintf("%s requires libseccomp >= %d.%d.%d and API level >= %d "+ - "(current version: %d.%d.%d, API level: %d)", - e.op, e.major, e.minor, e.micro, e.minAPI, - verMajor, verMinor, verMicro, e.curAPI) - } - return fmt.Sprintf("%s requires libseccomp >= %d.%d.%d (current version: %d.%d.%d)", - e.op, e.major, e.minor, e.micro, verMajor, verMinor, verMicro) -} - -// ScmpArch represents a CPU architecture. Seccomp can restrict syscalls on a -// per-architecture basis. -type ScmpArch uint - -// ScmpAction represents an action to be taken on a filter rule match in -// libseccomp -type ScmpAction uint - -// ScmpCompareOp represents a comparison operator which can be used in a filter -// rule -type ScmpCompareOp uint - -// ScmpCondition represents a rule in a libseccomp filter context -type ScmpCondition struct { - Argument uint `json:"argument,omitempty"` - Op ScmpCompareOp `json:"operator,omitempty"` - Operand1 uint64 `json:"operand_one,omitempty"` - Operand2 uint64 `json:"operand_two,omitempty"` -} - -// Seccomp userspace notification structures associated with filters that use the ActNotify action. - -// ScmpSyscall identifies a Linux System Call by its number. -type ScmpSyscall int32 - -// ScmpFd represents a file-descriptor used for seccomp userspace notifications. -type ScmpFd int32 - -// ScmpNotifData describes the system call context that triggered a notification. -// -// Syscall: the syscall number -// Arch: the filter architecture -// InstrPointer: address of the instruction that triggered a notification -// Args: arguments (up to 6) for the syscall -// -type ScmpNotifData struct { - Syscall ScmpSyscall `json:"syscall,omitempty"` - Arch ScmpArch `json:"arch,omitempty"` - InstrPointer uint64 `json:"instr_pointer,omitempty"` - Args []uint64 `json:"args,omitempty"` -} - -// ScmpNotifReq represents a seccomp userspace notification. See NotifReceive() for -// info on how to pull such a notification. -// -// ID: notification ID -// Pid: process that triggered the notification event -// Flags: filter flags (see seccomp(2)) -// Data: system call context that triggered the notification -// -type ScmpNotifReq struct { - ID uint64 `json:"id,omitempty"` - Pid uint32 `json:"pid,omitempty"` - Flags uint32 `json:"flags,omitempty"` - Data ScmpNotifData `json:"data,omitempty"` -} - -// ScmpNotifResp represents a seccomp userspace notification response. See NotifRespond() -// for info on how to push such a response. -// -// ID: notification ID (must match the corresponding ScmpNotifReq ID) -// Error: must be 0 if no error occurred, or an error constant from package -// syscall (e.g., syscall.EPERM, etc). In the latter case, it's used -// as an error return from the syscall that created the notification. -// Val: return value for the syscall that created the notification. Only -// relevant if Error is 0. -// Flags: userspace notification response flag (e.g., NotifRespFlagContinue) -// -type ScmpNotifResp struct { - ID uint64 `json:"id,omitempty"` - Error int32 `json:"error,omitempty"` - Val uint64 `json:"val,omitempty"` - Flags uint32 `json:"flags,omitempty"` -} - -// Exported Constants - -const ( - // Valid architectures recognized by libseccomp - // PowerPC and S390(x) architectures are unavailable below library version - // v2.3.0 and will returns errors if used with incompatible libraries - - // ArchInvalid is a placeholder to ensure uninitialized ScmpArch - // variables are invalid - ArchInvalid ScmpArch = iota - // ArchNative is the native architecture of the kernel - ArchNative - // ArchX86 represents 32-bit x86 syscalls - ArchX86 - // ArchAMD64 represents 64-bit x86-64 syscalls - ArchAMD64 - // ArchX32 represents 64-bit x86-64 syscalls (32-bit pointers) - ArchX32 - // ArchARM represents 32-bit ARM syscalls - ArchARM - // ArchARM64 represents 64-bit ARM syscalls - ArchARM64 - // ArchMIPS represents 32-bit MIPS syscalls - ArchMIPS - // ArchMIPS64 represents 64-bit MIPS syscalls - ArchMIPS64 - // ArchMIPS64N32 represents 64-bit MIPS syscalls (32-bit pointers) - ArchMIPS64N32 - // ArchMIPSEL represents 32-bit MIPS syscalls (little endian) - ArchMIPSEL - // ArchMIPSEL64 represents 64-bit MIPS syscalls (little endian) - ArchMIPSEL64 - // ArchMIPSEL64N32 represents 64-bit MIPS syscalls (little endian, - // 32-bit pointers) - ArchMIPSEL64N32 - // ArchPPC represents 32-bit POWERPC syscalls - ArchPPC - // ArchPPC64 represents 64-bit POWER syscalls (big endian) - ArchPPC64 - // ArchPPC64LE represents 64-bit POWER syscalls (little endian) - ArchPPC64LE - // ArchS390 represents 31-bit System z/390 syscalls - ArchS390 - // ArchS390X represents 64-bit System z/390 syscalls - ArchS390X - // ArchPARISC represents 32-bit PA-RISC - ArchPARISC - // ArchPARISC64 represents 64-bit PA-RISC - ArchPARISC64 - // ArchRISCV64 represents RISCV64 - ArchRISCV64 -) - -const ( - // Supported actions on filter match - - // ActInvalid is a placeholder to ensure uninitialized ScmpAction - // variables are invalid - ActInvalid ScmpAction = iota - // ActKillThread kills the thread that violated the rule. - // All other threads from the same thread group will continue to execute. - ActKillThread - // ActTrap throws SIGSYS - ActTrap - // ActNotify triggers a userspace notification. This action is only usable when - // libseccomp API level 6 or higher is supported. - ActNotify - // ActErrno causes the syscall to return a negative error code. This - // code can be set with the SetReturnCode method - ActErrno - // ActTrace causes the syscall to notify tracing processes with the - // given error code. This code can be set with the SetReturnCode method - ActTrace - // ActAllow permits the syscall to continue execution - ActAllow - // ActLog permits the syscall to continue execution after logging it. - // This action is only usable when libseccomp API level 3 or higher is - // supported. - ActLog - // ActKillProcess kills the process that violated the rule. - // All threads in the thread group are also terminated. - // This action is only usable when libseccomp API level 3 or higher is - // supported. - ActKillProcess - // ActKill kills the thread that violated the rule. - // All other threads from the same thread group will continue to execute. - // - // Deprecated: use ActKillThread - ActKill = ActKillThread -) - -const ( - // These are comparison operators used in conditional seccomp rules - // They are used to compare the value of a single argument of a syscall - // against a user-defined constant - - // CompareInvalid is a placeholder to ensure uninitialized ScmpCompareOp - // variables are invalid - CompareInvalid ScmpCompareOp = iota - // CompareNotEqual returns true if the argument is not equal to the - // given value - CompareNotEqual - // CompareLess returns true if the argument is less than the given value - CompareLess - // CompareLessOrEqual returns true if the argument is less than or equal - // to the given value - CompareLessOrEqual - // CompareEqual returns true if the argument is equal to the given value - CompareEqual - // CompareGreaterEqual returns true if the argument is greater than or - // equal to the given value - CompareGreaterEqual - // CompareGreater returns true if the argument is greater than the given - // value - CompareGreater - // CompareMaskedEqual returns true if the masked argument value is - // equal to the masked datum value. Mask is the first argument, and - // datum is the second one. - CompareMaskedEqual -) - -// ErrSyscallDoesNotExist represents an error condition where -// libseccomp is unable to resolve the syscall. -var ErrSyscallDoesNotExist = errors.New("could not resolve syscall name") - -const ( - // Userspace notification response flags - - // NotifRespFlagContinue tells the kernel to continue executing the system - // call that triggered the notification. Must only be used when the notification - // response's error is 0. - NotifRespFlagContinue uint32 = 1 -) - -// Helpers for types - -// GetArchFromString returns an ScmpArch constant from a string representing an -// architecture -func GetArchFromString(arch string) (ScmpArch, error) { - if err := ensureSupportedVersion(); err != nil { - return ArchInvalid, err - } - - switch strings.ToLower(arch) { - case "x86": - return ArchX86, nil - case "amd64", "x86-64", "x86_64", "x64": - return ArchAMD64, nil - case "x32": - return ArchX32, nil - case "arm": - return ArchARM, nil - case "arm64", "aarch64": - return ArchARM64, nil - case "mips": - return ArchMIPS, nil - case "mips64": - return ArchMIPS64, nil - case "mips64n32": - return ArchMIPS64N32, nil - case "mipsel": - return ArchMIPSEL, nil - case "mipsel64": - return ArchMIPSEL64, nil - case "mipsel64n32": - return ArchMIPSEL64N32, nil - case "ppc": - return ArchPPC, nil - case "ppc64": - return ArchPPC64, nil - case "ppc64le": - return ArchPPC64LE, nil - case "s390": - return ArchS390, nil - case "s390x": - return ArchS390X, nil - case "parisc": - return ArchPARISC, nil - case "parisc64": - return ArchPARISC64, nil - case "riscv64": - return ArchRISCV64, nil - default: - return ArchInvalid, fmt.Errorf("cannot convert unrecognized string %q", arch) - } -} - -// String returns a string representation of an architecture constant -func (a ScmpArch) String() string { - switch a { - case ArchX86: - return "x86" - case ArchAMD64: - return "amd64" - case ArchX32: - return "x32" - case ArchARM: - return "arm" - case ArchARM64: - return "arm64" - case ArchMIPS: - return "mips" - case ArchMIPS64: - return "mips64" - case ArchMIPS64N32: - return "mips64n32" - case ArchMIPSEL: - return "mipsel" - case ArchMIPSEL64: - return "mipsel64" - case ArchMIPSEL64N32: - return "mipsel64n32" - case ArchPPC: - return "ppc" - case ArchPPC64: - return "ppc64" - case ArchPPC64LE: - return "ppc64le" - case ArchS390: - return "s390" - case ArchS390X: - return "s390x" - case ArchPARISC: - return "parisc" - case ArchPARISC64: - return "parisc64" - case ArchRISCV64: - return "riscv64" - case ArchNative: - return "native" - case ArchInvalid: - return "Invalid architecture" - default: - return fmt.Sprintf("Unknown architecture %#x", uint(a)) - } -} - -// String returns a string representation of a comparison operator constant -func (a ScmpCompareOp) String() string { - switch a { - case CompareNotEqual: - return "Not equal" - case CompareLess: - return "Less than" - case CompareLessOrEqual: - return "Less than or equal to" - case CompareEqual: - return "Equal" - case CompareGreaterEqual: - return "Greater than or equal to" - case CompareGreater: - return "Greater than" - case CompareMaskedEqual: - return "Masked equality" - case CompareInvalid: - return "Invalid comparison operator" - default: - return fmt.Sprintf("Unrecognized comparison operator %#x", uint(a)) - } -} - -// String returns a string representation of a seccomp match action -func (a ScmpAction) String() string { - switch a & 0xFFFF { - case ActKillThread: - return "Action: Kill thread" - case ActKillProcess: - return "Action: Kill process" - case ActTrap: - return "Action: Send SIGSYS" - case ActErrno: - return fmt.Sprintf("Action: Return error code %d", (a >> 16)) - case ActTrace: - return fmt.Sprintf("Action: Notify tracing processes with code %d", - (a >> 16)) - case ActNotify: - return "Action: Notify userspace" - case ActLog: - return "Action: Log system call" - case ActAllow: - return "Action: Allow system call" - default: - return fmt.Sprintf("Unrecognized Action %#x", uint(a)) - } -} - -// SetReturnCode adds a return code to a supporting ScmpAction, clearing any -// existing code Only valid on ActErrno and ActTrace. Takes no action otherwise. -// Accepts 16-bit return code as argument. -// Returns a valid ScmpAction of the original type with the new error code set. -func (a ScmpAction) SetReturnCode(code int16) ScmpAction { - aTmp := a & 0x0000FFFF - if aTmp == ActErrno || aTmp == ActTrace { - return (aTmp | (ScmpAction(code)&0xFFFF)<<16) - } - return a -} - -// GetReturnCode returns the return code of an ScmpAction -func (a ScmpAction) GetReturnCode() int16 { - return int16(a >> 16) -} - -// General utility functions - -// GetLibraryVersion returns the version of the library the bindings are built -// against. -// The version is formatted as follows: Major.Minor.Micro -func GetLibraryVersion() (major, minor, micro uint) { - return verMajor, verMinor, verMicro -} - -// GetAPI returns the API level supported by the system. -// Returns a positive int containing the API level, or 0 with an error if the -// API level could not be detected due to the library being older than v2.4.0. -// See the seccomp_api_get(3) man page for details on available API levels: -// https://github.com/seccomp/libseccomp/blob/main/doc/man/man3/seccomp_api_get.3 -func GetAPI() (uint, error) { - return getAPI() -} - -// SetAPI forcibly sets the API level. General use of this function is strongly -// discouraged. -// Returns an error if the API level could not be set. An error is always -// returned if the library is older than v2.4.0 -// See the seccomp_api_get(3) man page for details on available API levels: -// https://github.com/seccomp/libseccomp/blob/main/doc/man/man3/seccomp_api_get.3 -func SetAPI(api uint) error { - return setAPI(api) -} - -// Syscall functions - -// GetName retrieves the name of a syscall from its number. -// Acts on any syscall number. -// Returns either a string containing the name of the syscall, or an error. -func (s ScmpSyscall) GetName() (string, error) { - return s.GetNameByArch(ArchNative) -} - -// GetNameByArch retrieves the name of a syscall from its number for a given -// architecture. -// Acts on any syscall number. -// Accepts a valid architecture constant. -// Returns either a string containing the name of the syscall, or an error. -// if the syscall is unrecognized or an issue occurred. -func (s ScmpSyscall) GetNameByArch(arch ScmpArch) (string, error) { - if err := sanitizeArch(arch); err != nil { - return "", err - } - - cString := C.seccomp_syscall_resolve_num_arch(arch.toNative(), C.int(s)) - if cString == nil { - return "", ErrSyscallDoesNotExist - } - defer C.free(unsafe.Pointer(cString)) - - finalStr := C.GoString(cString) - return finalStr, nil -} - -// GetSyscallFromName returns the number of a syscall by name on the kernel's -// native architecture. -// Accepts a string containing the name of a syscall. -// Returns the number of the syscall, or an error if no syscall with that name -// was found. -func GetSyscallFromName(name string) (ScmpSyscall, error) { - if err := ensureSupportedVersion(); err != nil { - return 0, err - } - - cString := C.CString(name) - defer C.free(unsafe.Pointer(cString)) - - result := C.seccomp_syscall_resolve_name(cString) - if result == scmpError { - return 0, ErrSyscallDoesNotExist - } - - return ScmpSyscall(result), nil -} - -// GetSyscallFromNameByArch returns the number of a syscall by name for a given -// architecture's ABI. -// Accepts the name of a syscall and an architecture constant. -// Returns the number of the syscall, or an error if an invalid architecture is -// passed or a syscall with that name was not found. -func GetSyscallFromNameByArch(name string, arch ScmpArch) (ScmpSyscall, error) { - if err := ensureSupportedVersion(); err != nil { - return 0, err - } - if err := sanitizeArch(arch); err != nil { - return 0, err - } - - cString := C.CString(name) - defer C.free(unsafe.Pointer(cString)) - - result := C.seccomp_syscall_resolve_name_arch(arch.toNative(), cString) - if result == scmpError { - return 0, ErrSyscallDoesNotExist - } - - return ScmpSyscall(result), nil -} - -// MakeCondition creates and returns a new condition to attach to a filter rule. -// Associated rules will only match if this condition is true. -// Accepts the number the argument we are checking, and a comparison operator -// and value to compare to. -// The rule will match if argument $arg (zero-indexed) of the syscall is -// $COMPARE_OP the provided comparison value. -// Some comparison operators accept two values. Masked equals, for example, -// will mask $arg of the syscall with the second value provided (via bitwise -// AND) and then compare against the first value provided. -// For example, in the less than or equal case, if the syscall argument was -// 0 and the value provided was 1, the condition would match, as 0 is less -// than or equal to 1. -// Return either an error on bad argument or a valid ScmpCondition struct. -func MakeCondition(arg uint, comparison ScmpCompareOp, values ...uint64) (ScmpCondition, error) { - var condStruct ScmpCondition - - if err := ensureSupportedVersion(); err != nil { - return condStruct, err - } - - if err := sanitizeCompareOp(comparison); err != nil { - return condStruct, err - } else if arg > 5 { - return condStruct, fmt.Errorf("syscalls only have up to 6 arguments (%d given)", arg) - } else if len(values) > 2 { - return condStruct, fmt.Errorf("conditions can have at most 2 arguments (%d given)", len(values)) - } else if len(values) == 0 { - return condStruct, errors.New("must provide at least one value to compare against") - } - - condStruct.Argument = arg - condStruct.Op = comparison - condStruct.Operand1 = values[0] - if len(values) == 2 { - condStruct.Operand2 = values[1] - } else { - condStruct.Operand2 = 0 // Unused - } - - return condStruct, nil -} - -// Utility Functions - -// GetNativeArch returns architecture token representing the native kernel -// architecture -func GetNativeArch() (ScmpArch, error) { - if err := ensureSupportedVersion(); err != nil { - return ArchInvalid, err - } - - arch := C.seccomp_arch_native() - - return archFromNative(arch) -} - -// Public Filter API - -// ScmpFilter represents a filter context in libseccomp. -// A filter context is initially empty. Rules can be added to it, and it can -// then be loaded into the kernel. -type ScmpFilter struct { - filterCtx C.scmp_filter_ctx - valid bool - lock sync.Mutex -} - -// NewFilter creates and returns a new filter context. Accepts a default action to be -// taken for syscalls which match no rules in the filter. -// Returns a reference to a valid filter context, or nil and an error -// if the filter context could not be created or an invalid default action was given. -func NewFilter(defaultAction ScmpAction) (*ScmpFilter, error) { - if err := ensureSupportedVersion(); err != nil { - return nil, err - } - - if err := sanitizeAction(defaultAction); err != nil { - return nil, err - } - - fPtr := C.seccomp_init(defaultAction.toNative()) - if fPtr == nil { - return nil, errors.New("could not create filter") - } - - filter := new(ScmpFilter) - filter.filterCtx = fPtr - filter.valid = true - runtime.SetFinalizer(filter, filterFinalizer) - - // Enable TSync so all goroutines will receive the same rules. - // If the kernel does not support TSYNC, allow us to continue without error. - if err := filter.setFilterAttr(filterAttrTsync, 0x1); err != nil && err != syscall.ENOTSUP { - filter.Release() - return nil, fmt.Errorf("could not create filter: error setting tsync bit: %w", err) - } - - return filter, nil -} - -// IsValid determines whether a filter context is valid to use. -// Some operations (Release and Merge) render filter contexts invalid and -// consequently prevent further use. -func (f *ScmpFilter) IsValid() bool { - f.lock.Lock() - defer f.lock.Unlock() - - return f.valid -} - -// Reset resets a filter context, removing all its existing state. -// Accepts a new default action to be taken for syscalls which do not match. -// Returns an error if the filter or action provided are invalid. -func (f *ScmpFilter) Reset(defaultAction ScmpAction) error { - f.lock.Lock() - defer f.lock.Unlock() - - if err := sanitizeAction(defaultAction); err != nil { - return err - } else if !f.valid { - return errBadFilter - } - - if retCode := C.seccomp_reset(f.filterCtx, defaultAction.toNative()); retCode != 0 { - return errRc(retCode) - } - - return nil -} - -// Release releases a filter context, freeing its memory. Should be called after -// loading into the kernel, when the filter is no longer needed. -// After calling this function, the given filter is no longer valid and cannot -// be used. -// Release() will be invoked automatically when a filter context is garbage -// collected, but can also be called manually to free memory. -func (f *ScmpFilter) Release() { - f.lock.Lock() - defer f.lock.Unlock() - - if !f.valid { - return - } - - f.valid = false - C.seccomp_release(f.filterCtx) -} - -// Merge merges two filter contexts. -// The source filter src will be released as part of the process, and will no -// longer be usable or valid after this call. -// To be merged, filters must NOT share any architectures, and all their -// attributes (Default Action, Bad Arch Action, and No New Privs bools) -// must match. -// The filter src will be merged into the filter this is called on. -// The architectures of the src filter not present in the destination, and all -// associated rules, will be added to the destination. -// Returns an error if merging the filters failed. -func (f *ScmpFilter) Merge(src *ScmpFilter) error { - f.lock.Lock() - defer f.lock.Unlock() - - src.lock.Lock() - defer src.lock.Unlock() - - if !src.valid || !f.valid { - return errors.New("one or more of the filter contexts is invalid or uninitialized") - } - - // Merge the filters - if retCode := C.seccomp_merge(f.filterCtx, src.filterCtx); retCode != 0 { - e := errRc(retCode) - if e == syscall.EINVAL { - return fmt.Errorf("filters could not be merged due to a mismatch in attributes or invalid filter: %w", e) - } - return e - } - - src.valid = false - - return nil -} - -// IsArchPresent checks if an architecture is present in a filter. -// If a filter contains an architecture, it uses its default action for -// syscalls which do not match rules in it, and its rules can match syscalls -// for that ABI. -// If a filter does not contain an architecture, all syscalls made to that -// kernel ABI will fail with the filter's default Bad Architecture Action -// (by default, killing the process). -// Accepts an architecture constant. -// Returns true if the architecture is present in the filter, false otherwise, -// and an error on an invalid filter context, architecture constant, or an -// issue with the call to libseccomp. -func (f *ScmpFilter) IsArchPresent(arch ScmpArch) (bool, error) { - f.lock.Lock() - defer f.lock.Unlock() - - if err := sanitizeArch(arch); err != nil { - return false, err - } else if !f.valid { - return false, errBadFilter - } - - if retCode := C.seccomp_arch_exist(f.filterCtx, arch.toNative()); retCode != 0 { - e := errRc(retCode) - if e == syscall.EEXIST { - // -EEXIST is "arch not present" - return false, nil - } - return false, e - } - - return true, nil -} - -// AddArch adds an architecture to the filter. -// Accepts an architecture constant. -// Returns an error on invalid filter context or architecture token, or an -// issue with the call to libseccomp. -func (f *ScmpFilter) AddArch(arch ScmpArch) error { - f.lock.Lock() - defer f.lock.Unlock() - - if err := sanitizeArch(arch); err != nil { - return err - } else if !f.valid { - return errBadFilter - } - - // Libseccomp returns -EEXIST if the specified architecture is already - // present. Succeed silently in this case, as it's not fatal, and the - // architecture is present already. - if retCode := C.seccomp_arch_add(f.filterCtx, arch.toNative()); retCode != 0 { - if e := errRc(retCode); e != syscall.EEXIST { - return e - } - } - - return nil -} - -// RemoveArch removes an architecture from the filter. -// Accepts an architecture constant. -// Returns an error on invalid filter context or architecture token, or an -// issue with the call to libseccomp. -func (f *ScmpFilter) RemoveArch(arch ScmpArch) error { - f.lock.Lock() - defer f.lock.Unlock() - - if err := sanitizeArch(arch); err != nil { - return err - } else if !f.valid { - return errBadFilter - } - - // Similar to AddArch, -EEXIST is returned if the arch is not present - // Succeed silently in that case, this is not fatal and the architecture - // is not present in the filter after RemoveArch - if retCode := C.seccomp_arch_remove(f.filterCtx, arch.toNative()); retCode != 0 { - if e := errRc(retCode); e != syscall.EEXIST { - return e - } - } - - return nil -} - -// Load loads a filter context into the kernel. -// Returns an error if the filter context is invalid or the syscall failed. -func (f *ScmpFilter) Load() error { - f.lock.Lock() - defer f.lock.Unlock() - - if !f.valid { - return errBadFilter - } - - if retCode := C.seccomp_load(f.filterCtx); retCode != 0 { - return errRc(retCode) - } - - return nil -} - -// GetDefaultAction returns the default action taken on a syscall which does not -// match a rule in the filter, or an error if an issue was encountered -// retrieving the value. -func (f *ScmpFilter) GetDefaultAction() (ScmpAction, error) { - action, err := f.getFilterAttr(filterAttrActDefault) - if err != nil { - return 0x0, err - } - - return actionFromNative(action) -} - -// GetBadArchAction returns the default action taken on a syscall for an -// architecture not in the filter, or an error if an issue was encountered -// retrieving the value. -func (f *ScmpFilter) GetBadArchAction() (ScmpAction, error) { - action, err := f.getFilterAttr(filterAttrActBadArch) - if err != nil { - return 0x0, err - } - - return actionFromNative(action) -} - -// GetNoNewPrivsBit returns the current state the No New Privileges bit will be set -// to on the filter being loaded, or an error if an issue was encountered -// retrieving the value. -// The No New Privileges bit tells the kernel that new processes run with exec() -// cannot gain more privileges than the process that ran exec(). -// For example, a process with No New Privileges set would be unable to exec -// setuid/setgid executables. -func (f *ScmpFilter) GetNoNewPrivsBit() (bool, error) { - noNewPrivs, err := f.getFilterAttr(filterAttrNNP) - if err != nil { - return false, err - } - - if noNewPrivs == 0 { - return false, nil - } - - return true, nil -} - -// GetLogBit returns the current state the Log bit will be set to on the filter -// being loaded, or an error if an issue was encountered retrieving the value. -// The Log bit tells the kernel that all actions taken by the filter, with the -// exception of ActAllow, should be logged. -// The Log bit is only usable when libseccomp API level 3 or higher is -// supported. -func (f *ScmpFilter) GetLogBit() (bool, error) { - log, err := f.getFilterAttr(filterAttrLog) - if err != nil { - if e := checkAPI("GetLogBit", 3, 2, 4, 0); e != nil { - err = e - } - - return false, err - } - - if log == 0 { - return false, nil - } - - return true, nil -} - -// GetSSB returns the current state the SSB bit will be set to on the filter -// being loaded, or an error if an issue was encountered retrieving the value. -// The SSB bit tells the kernel that a seccomp user is not interested in enabling -// Speculative Store Bypass mitigation. -// The SSB bit is only usable when libseccomp API level 4 or higher is -// supported. -func (f *ScmpFilter) GetSSB() (bool, error) { - ssb, err := f.getFilterAttr(filterAttrSSB) - if err != nil { - if e := checkAPI("GetSSB", 4, 2, 5, 0); e != nil { - err = e - } - - return false, err - } - - if ssb == 0 { - return false, nil - } - - return true, nil -} - -// GetOptimize returns the current optimization level of the filter, -// or an error if an issue was encountered retrieving the value. -// See SetOptimize for more details. -func (f *ScmpFilter) GetOptimize() (int, error) { - level, err := f.getFilterAttr(filterAttrOptimize) - if err != nil { - if e := checkAPI("GetOptimize", 4, 2, 5, 0); e != nil { - err = e - } - - return 0, err - } - - return int(level), nil -} - -// GetRawRC returns the current state of RawRC flag, or an error -// if an issue was encountered retrieving the value. -// See SetRawRC for more details. -func (f *ScmpFilter) GetRawRC() (bool, error) { - rawrc, err := f.getFilterAttr(filterAttrRawRC) - if err != nil { - if e := checkAPI("GetRawRC", 4, 2, 5, 0); e != nil { - err = e - } - - return false, err - } - - if rawrc == 0 { - return false, nil - } - - return true, nil -} - -// SetBadArchAction sets the default action taken on a syscall for an -// architecture not in the filter, or an error if an issue was encountered -// setting the value. -func (f *ScmpFilter) SetBadArchAction(action ScmpAction) error { - if err := sanitizeAction(action); err != nil { - return err - } - - return f.setFilterAttr(filterAttrActBadArch, action.toNative()) -} - -// SetNoNewPrivsBit sets the state of the No New Privileges bit, which will be -// applied on filter load, or an error if an issue was encountered setting the -// value. -// Filters with No New Privileges set to 0 can only be loaded if the process -// has the CAP_SYS_ADMIN capability. -func (f *ScmpFilter) SetNoNewPrivsBit(state bool) error { - var toSet C.uint32_t = 0x0 - - if state { - toSet = 0x1 - } - - return f.setFilterAttr(filterAttrNNP, toSet) -} - -// SetLogBit sets the state of the Log bit, which will be applied on filter -// load, or an error if an issue was encountered setting the value. -// The Log bit is only usable when libseccomp API level 3 or higher is -// supported. -func (f *ScmpFilter) SetLogBit(state bool) error { - var toSet C.uint32_t = 0x0 - - if state { - toSet = 0x1 - } - - err := f.setFilterAttr(filterAttrLog, toSet) - if err != nil { - if e := checkAPI("SetLogBit", 3, 2, 4, 0); e != nil { - err = e - } - } - - return err -} - -// SetSSB sets the state of the SSB bit, which will be applied on filter -// load, or an error if an issue was encountered setting the value. -// The SSB bit is only usable when libseccomp API level 4 or higher is -// supported. -func (f *ScmpFilter) SetSSB(state bool) error { - var toSet C.uint32_t = 0x0 - - if state { - toSet = 0x1 - } - - err := f.setFilterAttr(filterAttrSSB, toSet) - if err != nil { - if e := checkAPI("SetSSB", 4, 2, 5, 0); e != nil { - err = e - } - } - - return err -} - -// SetOptimize sets optimization level of the seccomp filter. By default -// libseccomp generates a set of sequential "if" statements for each rule in -// the filter. SetSyscallPriority can be used to prioritize the order for the -// default cause. The binary tree optimization sorts by syscall numbers and -// generates consistent O(log n) filter traversal for every rule in the filter. -// The binary tree may be advantageous for large filters. Note that -// SetSyscallPriority is ignored when level == 2. -// -// The different optimization levels are: -// 0: Reserved value, not currently used. -// 1: Rules sorted by priority and complexity (DEFAULT). -// 2: Binary tree sorted by syscall number. -func (f *ScmpFilter) SetOptimize(level int) error { - cLevel := C.uint32_t(level) - - err := f.setFilterAttr(filterAttrOptimize, cLevel) - if err != nil { - if e := checkAPI("SetOptimize", 4, 2, 5, 0); e != nil { - err = e - } - } - - return err -} - -// SetRawRC sets whether libseccomp should pass system error codes back to the -// caller, instead of the default ECANCELED. Defaults to false. -func (f *ScmpFilter) SetRawRC(state bool) error { - var toSet C.uint32_t = 0x0 - - if state { - toSet = 0x1 - } - - err := f.setFilterAttr(filterAttrRawRC, toSet) - if err != nil { - if e := checkAPI("SetRawRC", 4, 2, 5, 0); e != nil { - err = e - } - } - - return err -} - -// SetSyscallPriority sets a syscall's priority. -// This provides a hint to the filter generator in libseccomp about the -// importance of this syscall. High-priority syscalls are placed -// first in the filter code, and incur less overhead (at the expense of -// lower-priority syscalls). -func (f *ScmpFilter) SetSyscallPriority(call ScmpSyscall, priority uint8) error { - f.lock.Lock() - defer f.lock.Unlock() - - if !f.valid { - return errBadFilter - } - - if retCode := C.seccomp_syscall_priority(f.filterCtx, C.int(call), - C.uint8_t(priority)); retCode != 0 { - return errRc(retCode) - } - - return nil -} - -// AddRule adds a single rule for an unconditional action on a syscall. -// Accepts the number of the syscall and the action to be taken on the call -// being made. -// Returns an error if an issue was encountered adding the rule. -func (f *ScmpFilter) AddRule(call ScmpSyscall, action ScmpAction) error { - return f.addRuleGeneric(call, action, false, nil) -} - -// AddRuleExact adds a single rule for an unconditional action on a syscall. -// Accepts the number of the syscall and the action to be taken on the call -// being made. -// No modifications will be made to the rule, and it will fail to add if it -// cannot be applied to the current architecture without modification. -// The rule will function exactly as described, but it may not function identically -// (or be able to be applied to) all architectures. -// Returns an error if an issue was encountered adding the rule. -func (f *ScmpFilter) AddRuleExact(call ScmpSyscall, action ScmpAction) error { - return f.addRuleGeneric(call, action, true, nil) -} - -// AddRuleConditional adds a single rule for a conditional action on a syscall. -// Returns an error if an issue was encountered adding the rule. -// All conditions must match for the rule to match. -func (f *ScmpFilter) AddRuleConditional(call ScmpSyscall, action ScmpAction, conds []ScmpCondition) error { - return f.addRuleGeneric(call, action, false, conds) -} - -// AddRuleConditionalExact adds a single rule for a conditional action on a -// syscall. -// No modifications will be made to the rule, and it will fail to add if it -// cannot be applied to the current architecture without modification. -// The rule will function exactly as described, but it may not function identically -// (or be able to be applied to) all architectures. -// Returns an error if an issue was encountered adding the rule. -func (f *ScmpFilter) AddRuleConditionalExact(call ScmpSyscall, action ScmpAction, conds []ScmpCondition) error { - return f.addRuleGeneric(call, action, true, conds) -} - -// ExportPFC output PFC-formatted, human-readable dump of a filter context's -// rules to a file. -// Accepts file to write to (must be open for writing). -// Returns an error if writing to the file fails. -func (f *ScmpFilter) ExportPFC(file *os.File) error { - f.lock.Lock() - defer f.lock.Unlock() - - fd := file.Fd() - - if !f.valid { - return errBadFilter - } - - if retCode := C.seccomp_export_pfc(f.filterCtx, C.int(fd)); retCode != 0 { - return errRc(retCode) - } - - return nil -} - -// ExportBPF outputs Berkeley Packet Filter-formatted, kernel-readable dump of a -// filter context's rules to a file. -// Accepts file to write to (must be open for writing). -// Returns an error if writing to the file fails. -func (f *ScmpFilter) ExportBPF(file *os.File) error { - f.lock.Lock() - defer f.lock.Unlock() - - fd := file.Fd() - - if !f.valid { - return errBadFilter - } - - if retCode := C.seccomp_export_bpf(f.filterCtx, C.int(fd)); retCode != 0 { - return errRc(retCode) - } - - return nil -} - -// Userspace Notification API - -// GetNotifFd returns the userspace notification file descriptor associated with the given -// filter context. Such a file descriptor is only valid after the filter has been loaded -// and only when the filter uses the ActNotify action. The file descriptor can be used to -// retrieve and respond to notifications associated with the filter (see NotifReceive(), -// NotifRespond(), and NotifIDValid()). -func (f *ScmpFilter) GetNotifFd() (ScmpFd, error) { - return f.getNotifFd() -} - -// NotifReceive retrieves a seccomp userspace notification from a filter whose ActNotify -// action has triggered. The caller is expected to process the notification and return a -// response via NotifRespond(). Each invocation of this function returns one -// notification. As multiple notifications may be pending at any time, this function is -// normally called within a polling loop. -func NotifReceive(fd ScmpFd) (*ScmpNotifReq, error) { - return notifReceive(fd) -} - -// NotifRespond responds to a notification retrieved via NotifReceive(). The response Id -// must match that of the corresponding notification retrieved via NotifReceive(). -func NotifRespond(fd ScmpFd, scmpResp *ScmpNotifResp) error { - return notifRespond(fd, scmpResp) -} - -// NotifIDValid checks if a notification is still valid. An return value of nil means the -// notification is still valid. Otherwise the notification is not valid. This can be used -// to mitigate time-of-check-time-of-use (TOCTOU) attacks as described in seccomp_notify_id_valid(2). -func NotifIDValid(fd ScmpFd, id uint64) error { - return notifIDValid(fd, id) -} diff --git a/vendor/github.com/seccomp/libseccomp-golang/seccomp_internal.go b/vendor/github.com/seccomp/libseccomp-golang/seccomp_internal.go deleted file mode 100644 index 0a7fd34f510..00000000000 --- a/vendor/github.com/seccomp/libseccomp-golang/seccomp_internal.go +++ /dev/null @@ -1,884 +0,0 @@ -// Internal functions for libseccomp Go bindings -// No exported functions - -package seccomp - -import ( - "errors" - "fmt" - "syscall" -) - -// Unexported C wrapping code - provides the C-Golang interface -// Get the seccomp header in scope -// Need stdlib.h for free() on cstrings - -// To compile libseccomp-golang against a specific version of libseccomp: -// cd ../libseccomp && mkdir -p prefix -// ./configure --prefix=$PWD/prefix && make && make install -// cd ../libseccomp-golang -// PKG_CONFIG_PATH=$PWD/../libseccomp/prefix/lib/pkgconfig/ make -// LD_PRELOAD=$PWD/../libseccomp/prefix/lib/libseccomp.so.2.5.0 PKG_CONFIG_PATH=$PWD/../libseccomp/prefix/lib/pkgconfig/ make test - -// #cgo pkg-config: libseccomp -/* -#include -#include -#include - -#if (SCMP_VER_MAJOR < 2) || \ - (SCMP_VER_MAJOR == 2 && SCMP_VER_MINOR < 3) || \ - (SCMP_VER_MAJOR == 2 && SCMP_VER_MINOR == 3 && SCMP_VER_MICRO < 1) -#error This package requires libseccomp >= v2.3.1 -#endif - -#define ARCH_BAD ~0 - -const uint32_t C_ARCH_BAD = ARCH_BAD; - -#ifndef SCMP_ARCH_PPC -#define SCMP_ARCH_PPC ARCH_BAD -#endif - -#ifndef SCMP_ARCH_PPC64 -#define SCMP_ARCH_PPC64 ARCH_BAD -#endif - -#ifndef SCMP_ARCH_PPC64LE -#define SCMP_ARCH_PPC64LE ARCH_BAD -#endif - -#ifndef SCMP_ARCH_S390 -#define SCMP_ARCH_S390 ARCH_BAD -#endif - -#ifndef SCMP_ARCH_S390X -#define SCMP_ARCH_S390X ARCH_BAD -#endif - -#ifndef SCMP_ARCH_PARISC -#define SCMP_ARCH_PARISC ARCH_BAD -#endif - -#ifndef SCMP_ARCH_PARISC64 -#define SCMP_ARCH_PARISC64 ARCH_BAD -#endif - -#ifndef SCMP_ARCH_RISCV64 -#define SCMP_ARCH_RISCV64 ARCH_BAD -#endif - -const uint32_t C_ARCH_NATIVE = SCMP_ARCH_NATIVE; -const uint32_t C_ARCH_X86 = SCMP_ARCH_X86; -const uint32_t C_ARCH_X86_64 = SCMP_ARCH_X86_64; -const uint32_t C_ARCH_X32 = SCMP_ARCH_X32; -const uint32_t C_ARCH_ARM = SCMP_ARCH_ARM; -const uint32_t C_ARCH_AARCH64 = SCMP_ARCH_AARCH64; -const uint32_t C_ARCH_MIPS = SCMP_ARCH_MIPS; -const uint32_t C_ARCH_MIPS64 = SCMP_ARCH_MIPS64; -const uint32_t C_ARCH_MIPS64N32 = SCMP_ARCH_MIPS64N32; -const uint32_t C_ARCH_MIPSEL = SCMP_ARCH_MIPSEL; -const uint32_t C_ARCH_MIPSEL64 = SCMP_ARCH_MIPSEL64; -const uint32_t C_ARCH_MIPSEL64N32 = SCMP_ARCH_MIPSEL64N32; -const uint32_t C_ARCH_PPC = SCMP_ARCH_PPC; -const uint32_t C_ARCH_PPC64 = SCMP_ARCH_PPC64; -const uint32_t C_ARCH_PPC64LE = SCMP_ARCH_PPC64LE; -const uint32_t C_ARCH_S390 = SCMP_ARCH_S390; -const uint32_t C_ARCH_S390X = SCMP_ARCH_S390X; -const uint32_t C_ARCH_PARISC = SCMP_ARCH_PARISC; -const uint32_t C_ARCH_PARISC64 = SCMP_ARCH_PARISC64; -const uint32_t C_ARCH_RISCV64 = SCMP_ARCH_RISCV64; - -#ifndef SCMP_ACT_LOG -#define SCMP_ACT_LOG 0x7ffc0000U -#endif - -#ifndef SCMP_ACT_KILL_PROCESS -#define SCMP_ACT_KILL_PROCESS 0x80000000U -#endif - -#ifndef SCMP_ACT_KILL_THREAD -#define SCMP_ACT_KILL_THREAD 0x00000000U -#endif - -#ifndef SCMP_ACT_NOTIFY -#define SCMP_ACT_NOTIFY 0x7fc00000U -#endif - -const uint32_t C_ACT_KILL = SCMP_ACT_KILL; -const uint32_t C_ACT_KILL_PROCESS = SCMP_ACT_KILL_PROCESS; -const uint32_t C_ACT_KILL_THREAD = SCMP_ACT_KILL_THREAD; -const uint32_t C_ACT_TRAP = SCMP_ACT_TRAP; -const uint32_t C_ACT_ERRNO = SCMP_ACT_ERRNO(0); -const uint32_t C_ACT_TRACE = SCMP_ACT_TRACE(0); -const uint32_t C_ACT_LOG = SCMP_ACT_LOG; -const uint32_t C_ACT_ALLOW = SCMP_ACT_ALLOW; -const uint32_t C_ACT_NOTIFY = SCMP_ACT_NOTIFY; - -// The libseccomp SCMP_FLTATR_CTL_LOG member of the scmp_filter_attr enum was -// added in v2.4.0 -#if SCMP_VER_MAJOR == 2 && SCMP_VER_MINOR < 4 -#define SCMP_FLTATR_CTL_LOG _SCMP_FLTATR_MIN -#endif - -// The following SCMP_FLTATR_* were added in libseccomp v2.5.0. -#if SCMP_VER_MAJOR == 2 && SCMP_VER_MINOR < 5 -#define SCMP_FLTATR_CTL_SSB _SCMP_FLTATR_MIN -#define SCMP_FLTATR_CTL_OPTIMIZE _SCMP_FLTATR_MIN -#define SCMP_FLTATR_API_SYSRAWRC _SCMP_FLTATR_MIN -#endif - -const uint32_t C_ATTRIBUTE_DEFAULT = (uint32_t)SCMP_FLTATR_ACT_DEFAULT; -const uint32_t C_ATTRIBUTE_BADARCH = (uint32_t)SCMP_FLTATR_ACT_BADARCH; -const uint32_t C_ATTRIBUTE_NNP = (uint32_t)SCMP_FLTATR_CTL_NNP; -const uint32_t C_ATTRIBUTE_TSYNC = (uint32_t)SCMP_FLTATR_CTL_TSYNC; -const uint32_t C_ATTRIBUTE_LOG = (uint32_t)SCMP_FLTATR_CTL_LOG; -const uint32_t C_ATTRIBUTE_SSB = (uint32_t)SCMP_FLTATR_CTL_SSB; -const uint32_t C_ATTRIBUTE_OPTIMIZE = (uint32_t)SCMP_FLTATR_CTL_OPTIMIZE; -const uint32_t C_ATTRIBUTE_SYSRAWRC = (uint32_t)SCMP_FLTATR_API_SYSRAWRC; - -const int C_CMP_NE = (int)SCMP_CMP_NE; -const int C_CMP_LT = (int)SCMP_CMP_LT; -const int C_CMP_LE = (int)SCMP_CMP_LE; -const int C_CMP_EQ = (int)SCMP_CMP_EQ; -const int C_CMP_GE = (int)SCMP_CMP_GE; -const int C_CMP_GT = (int)SCMP_CMP_GT; -const int C_CMP_MASKED_EQ = (int)SCMP_CMP_MASKED_EQ; - -const int C_VERSION_MAJOR = SCMP_VER_MAJOR; -const int C_VERSION_MINOR = SCMP_VER_MINOR; -const int C_VERSION_MICRO = SCMP_VER_MICRO; - -#if SCMP_VER_MAJOR == 2 && SCMP_VER_MINOR >= 3 -unsigned int get_major_version() -{ - return seccomp_version()->major; -} - -unsigned int get_minor_version() -{ - return seccomp_version()->minor; -} - -unsigned int get_micro_version() -{ - return seccomp_version()->micro; -} -#else -unsigned int get_major_version() -{ - return (unsigned int)C_VERSION_MAJOR; -} - -unsigned int get_minor_version() -{ - return (unsigned int)C_VERSION_MINOR; -} - -unsigned int get_micro_version() -{ - return (unsigned int)C_VERSION_MICRO; -} -#endif - -// The libseccomp API level functions were added in v2.4.0 -#if SCMP_VER_MAJOR == 2 && SCMP_VER_MINOR < 4 -const unsigned int seccomp_api_get(void) -{ - // libseccomp-golang requires libseccomp v2.2.0, at a minimum, which - // supported API level 2. However, the kernel may not support API level - // 2 constructs which are the seccomp() system call and the TSYNC - // filter flag. Return the "reserved" value of 0 here to indicate that - // proper API level support is not available in libseccomp. - return 0; -} - -int seccomp_api_set(unsigned int level) -{ - return -EOPNOTSUPP; -} -#endif - -typedef struct scmp_arg_cmp* scmp_cast_t; - -void* make_arg_cmp_array(unsigned int length) -{ - return calloc(length, sizeof(struct scmp_arg_cmp)); -} - -// Wrapper to add an scmp_arg_cmp struct to an existing arg_cmp array -void add_struct_arg_cmp( - struct scmp_arg_cmp* arr, - unsigned int pos, - unsigned int arg, - int compare, - uint64_t a, - uint64_t b - ) -{ - arr[pos].arg = arg; - arr[pos].op = compare; - arr[pos].datum_a = a; - arr[pos].datum_b = b; - - return; -} - -// The seccomp notify API functions were added in v2.5.0 -#if SCMP_VER_MAJOR == 2 && SCMP_VER_MINOR < 5 - -struct seccomp_data { - int nr; - __u32 arch; - __u64 instruction_pointer; - __u64 args[6]; -}; - -struct seccomp_notif { - __u64 id; - __u32 pid; - __u32 flags; - struct seccomp_data data; -}; - -struct seccomp_notif_resp { - __u64 id; - __s64 val; - __s32 error; - __u32 flags; -}; - -int seccomp_notify_alloc(struct seccomp_notif **req, struct seccomp_notif_resp **resp) { - return -EOPNOTSUPP; -} -int seccomp_notify_fd(const scmp_filter_ctx ctx) { - return -EOPNOTSUPP; -} -void seccomp_notify_free(struct seccomp_notif *req, struct seccomp_notif_resp *resp) { -} -int seccomp_notify_id_valid(int fd, uint64_t id) { - return -EOPNOTSUPP; -} -int seccomp_notify_receive(int fd, struct seccomp_notif *req) { - return -EOPNOTSUPP; -} -int seccomp_notify_respond(int fd, struct seccomp_notif_resp *resp) { - return -EOPNOTSUPP; -} - -#endif -*/ -import "C" - -// Nonexported types -type scmpFilterAttr uint32 - -// Nonexported constants - -const ( - filterAttrActDefault scmpFilterAttr = iota - filterAttrActBadArch - filterAttrNNP - filterAttrTsync - filterAttrLog - filterAttrSSB - filterAttrOptimize - filterAttrRawRC -) - -const ( - // An error return from certain libseccomp functions - scmpError C.int = -1 - // Comparison boundaries to check for architecture validity - archStart ScmpArch = ArchNative - archEnd ScmpArch = ArchRISCV64 - // Comparison boundaries to check for action validity - actionStart ScmpAction = ActKillThread - actionEnd ScmpAction = ActKillProcess - // Comparison boundaries to check for comparison operator validity - compareOpStart ScmpCompareOp = CompareNotEqual - compareOpEnd ScmpCompareOp = CompareMaskedEqual -) - -var ( - // errBadFilter is thrown on bad filter context. - errBadFilter = errors.New("filter is invalid or uninitialized") - errDefAction = errors.New("requested action matches default action of filter") - // Constants representing library major, minor, and micro versions - verMajor = uint(C.get_major_version()) - verMinor = uint(C.get_minor_version()) - verMicro = uint(C.get_micro_version()) -) - -// Nonexported functions - -// checkVersion returns an error if the libseccomp version being used -// is less than the one specified by major, minor, and micro arguments. -// Argument op is an arbitrary non-empty operation description, which -// is used as a part of the error message returned. -// -// Most users should use checkAPI instead. -func checkVersion(op string, major, minor, micro uint) error { - if (verMajor > major) || - (verMajor == major && verMinor > minor) || - (verMajor == major && verMinor == minor && verMicro >= micro) { - return nil - } - return &VersionError{ - op: op, - major: major, - minor: minor, - micro: micro, - } -} - -func ensureSupportedVersion() error { - return checkVersion("seccomp", 2, 3, 1) -} - -// Get the API level -func getAPI() (uint, error) { - api := C.seccomp_api_get() - if api == 0 { - return 0, errors.New("API level operations are not supported") - } - - return uint(api), nil -} - -// Set the API level -func setAPI(api uint) error { - if retCode := C.seccomp_api_set(C.uint(api)); retCode != 0 { - e := errRc(retCode) - if e == syscall.EOPNOTSUPP { - return errors.New("API level operations are not supported") - } - - return fmt.Errorf("could not set API level: %w", e) - } - - return nil -} - -// Filter helpers - -// Filter finalizer - ensure that kernel context for filters is freed -func filterFinalizer(f *ScmpFilter) { - f.Release() -} - -func errRc(rc C.int) error { - return syscall.Errno(-1 * rc) -} - -// Get a raw filter attribute -func (f *ScmpFilter) getFilterAttr(attr scmpFilterAttr) (C.uint32_t, error) { - f.lock.Lock() - defer f.lock.Unlock() - - if !f.valid { - return 0x0, errBadFilter - } - - var attribute C.uint32_t - - retCode := C.seccomp_attr_get(f.filterCtx, attr.toNative(), &attribute) - if retCode != 0 { - return 0x0, errRc(retCode) - } - - return attribute, nil -} - -// Set a raw filter attribute -func (f *ScmpFilter) setFilterAttr(attr scmpFilterAttr, value C.uint32_t) error { - f.lock.Lock() - defer f.lock.Unlock() - - if !f.valid { - return errBadFilter - } - - retCode := C.seccomp_attr_set(f.filterCtx, attr.toNative(), value) - if retCode != 0 { - return errRc(retCode) - } - - return nil -} - -// DOES NOT LOCK OR CHECK VALIDITY -// Assumes caller has already done this -// Wrapper for seccomp_rule_add_... functions -func (f *ScmpFilter) addRuleWrapper(call ScmpSyscall, action ScmpAction, exact bool, length C.uint, cond C.scmp_cast_t) error { - if length != 0 && cond == nil { - return errors.New("null conditions list, but length is nonzero") - } - - var retCode C.int - if exact { - retCode = C.seccomp_rule_add_exact_array(f.filterCtx, action.toNative(), C.int(call), length, cond) - } else { - retCode = C.seccomp_rule_add_array(f.filterCtx, action.toNative(), C.int(call), length, cond) - } - - if retCode != 0 { - switch e := errRc(retCode); e { - case syscall.EFAULT: - return fmt.Errorf("unrecognized syscall %#x", int32(call)) - // libseccomp >= v2.5.0 returns EACCES, older versions return EPERM. - // TODO: remove EPERM once libseccomp < v2.5.0 is not supported. - case syscall.EPERM, syscall.EACCES: - return errDefAction - case syscall.EINVAL: - return errors.New("two checks on same syscall argument") - default: - return e - } - } - - return nil -} - -// Generic add function for filter rules -func (f *ScmpFilter) addRuleGeneric(call ScmpSyscall, action ScmpAction, exact bool, conds []ScmpCondition) error { - f.lock.Lock() - defer f.lock.Unlock() - - if !f.valid { - return errBadFilter - } - - if len(conds) == 0 { - if err := f.addRuleWrapper(call, action, exact, 0, nil); err != nil { - return err - } - } else { - argsArr := C.make_arg_cmp_array(C.uint(len(conds))) - if argsArr == nil { - return errors.New("error allocating memory for conditions") - } - defer C.free(argsArr) - - for i, cond := range conds { - C.add_struct_arg_cmp(C.scmp_cast_t(argsArr), C.uint(i), - C.uint(cond.Argument), cond.Op.toNative(), - C.uint64_t(cond.Operand1), C.uint64_t(cond.Operand2)) - } - - if err := f.addRuleWrapper(call, action, exact, C.uint(len(conds)), C.scmp_cast_t(argsArr)); err != nil { - return err - } - } - - return nil -} - -// Generic Helpers - -// Helper - Sanitize Arch token input -func sanitizeArch(in ScmpArch) error { - if in < archStart || in > archEnd { - return fmt.Errorf("unrecognized architecture %#x", uint(in)) - } - - if in.toNative() == C.C_ARCH_BAD { - return fmt.Errorf("architecture %v is not supported on this version of the library", in) - } - - return nil -} - -func sanitizeAction(in ScmpAction) error { - inTmp := in & 0x0000FFFF - if inTmp < actionStart || inTmp > actionEnd { - return fmt.Errorf("unrecognized action %#x", uint(inTmp)) - } - - if inTmp != ActTrace && inTmp != ActErrno && (in&0xFFFF0000) != 0 { - return errors.New("highest 16 bits must be zeroed except for Trace and Errno") - } - - return nil -} - -func sanitizeCompareOp(in ScmpCompareOp) error { - if in < compareOpStart || in > compareOpEnd { - return fmt.Errorf("unrecognized comparison operator %#x", uint(in)) - } - - return nil -} - -func archFromNative(a C.uint32_t) (ScmpArch, error) { - switch a { - case C.C_ARCH_X86: - return ArchX86, nil - case C.C_ARCH_X86_64: - return ArchAMD64, nil - case C.C_ARCH_X32: - return ArchX32, nil - case C.C_ARCH_ARM: - return ArchARM, nil - case C.C_ARCH_NATIVE: - return ArchNative, nil - case C.C_ARCH_AARCH64: - return ArchARM64, nil - case C.C_ARCH_MIPS: - return ArchMIPS, nil - case C.C_ARCH_MIPS64: - return ArchMIPS64, nil - case C.C_ARCH_MIPS64N32: - return ArchMIPS64N32, nil - case C.C_ARCH_MIPSEL: - return ArchMIPSEL, nil - case C.C_ARCH_MIPSEL64: - return ArchMIPSEL64, nil - case C.C_ARCH_MIPSEL64N32: - return ArchMIPSEL64N32, nil - case C.C_ARCH_PPC: - return ArchPPC, nil - case C.C_ARCH_PPC64: - return ArchPPC64, nil - case C.C_ARCH_PPC64LE: - return ArchPPC64LE, nil - case C.C_ARCH_S390: - return ArchS390, nil - case C.C_ARCH_S390X: - return ArchS390X, nil - case C.C_ARCH_PARISC: - return ArchPARISC, nil - case C.C_ARCH_PARISC64: - return ArchPARISC64, nil - case C.C_ARCH_RISCV64: - return ArchRISCV64, nil - default: - return 0x0, fmt.Errorf("unrecognized architecture %#x", uint32(a)) - } -} - -// Only use with sanitized arches, no error handling -func (a ScmpArch) toNative() C.uint32_t { - switch a { - case ArchX86: - return C.C_ARCH_X86 - case ArchAMD64: - return C.C_ARCH_X86_64 - case ArchX32: - return C.C_ARCH_X32 - case ArchARM: - return C.C_ARCH_ARM - case ArchARM64: - return C.C_ARCH_AARCH64 - case ArchMIPS: - return C.C_ARCH_MIPS - case ArchMIPS64: - return C.C_ARCH_MIPS64 - case ArchMIPS64N32: - return C.C_ARCH_MIPS64N32 - case ArchMIPSEL: - return C.C_ARCH_MIPSEL - case ArchMIPSEL64: - return C.C_ARCH_MIPSEL64 - case ArchMIPSEL64N32: - return C.C_ARCH_MIPSEL64N32 - case ArchPPC: - return C.C_ARCH_PPC - case ArchPPC64: - return C.C_ARCH_PPC64 - case ArchPPC64LE: - return C.C_ARCH_PPC64LE - case ArchS390: - return C.C_ARCH_S390 - case ArchS390X: - return C.C_ARCH_S390X - case ArchPARISC: - return C.C_ARCH_PARISC - case ArchPARISC64: - return C.C_ARCH_PARISC64 - case ArchRISCV64: - return C.C_ARCH_RISCV64 - case ArchNative: - return C.C_ARCH_NATIVE - default: - return 0x0 - } -} - -// Only use with sanitized ops, no error handling -func (a ScmpCompareOp) toNative() C.int { - switch a { - case CompareNotEqual: - return C.C_CMP_NE - case CompareLess: - return C.C_CMP_LT - case CompareLessOrEqual: - return C.C_CMP_LE - case CompareEqual: - return C.C_CMP_EQ - case CompareGreaterEqual: - return C.C_CMP_GE - case CompareGreater: - return C.C_CMP_GT - case CompareMaskedEqual: - return C.C_CMP_MASKED_EQ - default: - return 0x0 - } -} - -func actionFromNative(a C.uint32_t) (ScmpAction, error) { - aTmp := a & 0xFFFF - switch a & 0xFFFF0000 { - case C.C_ACT_KILL_PROCESS: - return ActKillProcess, nil - case C.C_ACT_KILL_THREAD: - return ActKillThread, nil - case C.C_ACT_TRAP: - return ActTrap, nil - case C.C_ACT_ERRNO: - return ActErrno.SetReturnCode(int16(aTmp)), nil - case C.C_ACT_TRACE: - return ActTrace.SetReturnCode(int16(aTmp)), nil - case C.C_ACT_LOG: - return ActLog, nil - case C.C_ACT_ALLOW: - return ActAllow, nil - case C.C_ACT_NOTIFY: - return ActNotify, nil - default: - return 0x0, fmt.Errorf("unrecognized action %#x", uint32(a)) - } -} - -// Only use with sanitized actions, no error handling -func (a ScmpAction) toNative() C.uint32_t { - switch a & 0xFFFF { - case ActKillProcess: - return C.C_ACT_KILL_PROCESS - case ActKillThread: - return C.C_ACT_KILL_THREAD - case ActTrap: - return C.C_ACT_TRAP - case ActErrno: - return C.C_ACT_ERRNO | (C.uint32_t(a) >> 16) - case ActTrace: - return C.C_ACT_TRACE | (C.uint32_t(a) >> 16) - case ActLog: - return C.C_ACT_LOG - case ActAllow: - return C.C_ACT_ALLOW - case ActNotify: - return C.C_ACT_NOTIFY - default: - return 0x0 - } -} - -// Internal only, assumes safe attribute -func (a scmpFilterAttr) toNative() uint32 { - switch a { - case filterAttrActDefault: - return uint32(C.C_ATTRIBUTE_DEFAULT) - case filterAttrActBadArch: - return uint32(C.C_ATTRIBUTE_BADARCH) - case filterAttrNNP: - return uint32(C.C_ATTRIBUTE_NNP) - case filterAttrTsync: - return uint32(C.C_ATTRIBUTE_TSYNC) - case filterAttrLog: - return uint32(C.C_ATTRIBUTE_LOG) - case filterAttrSSB: - return uint32(C.C_ATTRIBUTE_SSB) - case filterAttrOptimize: - return uint32(C.C_ATTRIBUTE_OPTIMIZE) - case filterAttrRawRC: - return uint32(C.C_ATTRIBUTE_SYSRAWRC) - default: - return 0x0 - } -} - -func syscallFromNative(a C.int) ScmpSyscall { - return ScmpSyscall(a) -} - -func notifReqFromNative(req *C.struct_seccomp_notif) (*ScmpNotifReq, error) { - scmpArgs := make([]uint64, 6) - for i := 0; i < len(scmpArgs); i++ { - scmpArgs[i] = uint64(req.data.args[i]) - } - - arch, err := archFromNative(req.data.arch) - if err != nil { - return nil, err - } - - scmpData := ScmpNotifData{ - Syscall: syscallFromNative(req.data.nr), - Arch: arch, - InstrPointer: uint64(req.data.instruction_pointer), - Args: scmpArgs, - } - - scmpReq := &ScmpNotifReq{ - ID: uint64(req.id), - Pid: uint32(req.pid), - Flags: uint32(req.flags), - Data: scmpData, - } - - return scmpReq, nil -} - -func (scmpResp *ScmpNotifResp) toNative(resp *C.struct_seccomp_notif_resp) { - resp.id = C.__u64(scmpResp.ID) - resp.val = C.__s64(scmpResp.Val) - resp.error = (C.__s32(scmpResp.Error) * -1) // kernel requires a negated value - resp.flags = C.__u32(scmpResp.Flags) -} - -// checkAPI checks that both the API level and the seccomp version is equal to -// or greater than the specified minLevel and major, minor, micro, -// respectively, and returns an error otherwise. Argument op is an arbitrary -// non-empty operation description, used as a part of the error message -// returned. -func checkAPI(op string, minLevel uint, major, minor, micro uint) error { - // Ignore error from getAPI, as it returns level == 0 in case of error. - level, _ := getAPI() - if level >= minLevel { - return checkVersion(op, major, minor, micro) - } - return &VersionError{ - op: op, - curAPI: level, - minAPI: minLevel, - major: major, - minor: minor, - micro: micro, - } -} - -// Userspace Notification API -// Calls to C.seccomp_notify* hidden from seccomp.go - -func notifSupported() error { - return checkAPI("seccomp notification", 6, 2, 5, 0) -} - -func (f *ScmpFilter) getNotifFd() (ScmpFd, error) { - f.lock.Lock() - defer f.lock.Unlock() - - if !f.valid { - return -1, errBadFilter - } - if err := notifSupported(); err != nil { - return -1, err - } - - fd := C.seccomp_notify_fd(f.filterCtx) - - return ScmpFd(fd), nil -} - -func notifReceive(fd ScmpFd) (*ScmpNotifReq, error) { - var req *C.struct_seccomp_notif - var resp *C.struct_seccomp_notif_resp - - if err := notifSupported(); err != nil { - return nil, err - } - - // we only use the request here; the response is unused - if retCode := C.seccomp_notify_alloc(&req, &resp); retCode != 0 { - return nil, errRc(retCode) - } - - defer func() { - C.seccomp_notify_free(req, resp) - }() - - for { - retCode, errno := C.seccomp_notify_receive(C.int(fd), req) - if retCode == 0 { - break - } - - if errno == syscall.EINTR { - continue - } - - if errno == syscall.ENOENT { - return nil, errno - } - - return nil, errRc(retCode) - } - - return notifReqFromNative(req) -} - -func notifRespond(fd ScmpFd, scmpResp *ScmpNotifResp) error { - var req *C.struct_seccomp_notif - var resp *C.struct_seccomp_notif_resp - - if err := notifSupported(); err != nil { - return err - } - - // we only use the response here; the request is discarded - if retCode := C.seccomp_notify_alloc(&req, &resp); retCode != 0 { - return errRc(retCode) - } - - defer func() { - C.seccomp_notify_free(req, resp) - }() - - scmpResp.toNative(resp) - - for { - retCode, errno := C.seccomp_notify_respond(C.int(fd), resp) - if retCode == 0 { - break - } - - if errno == syscall.EINTR { - continue - } - - if errno == syscall.ENOENT { - return errno - } - - return errRc(retCode) - } - - return nil -} - -func notifIDValid(fd ScmpFd, id uint64) error { - if err := notifSupported(); err != nil { - return err - } - - for { - retCode, errno := C.seccomp_notify_id_valid(C.int(fd), C.uint64_t(id)) - if retCode == 0 { - break - } - - if errno == syscall.EINTR { - continue - } - - if errno == syscall.ENOENT { - return errno - } - - return errRc(retCode) - } - - return nil -} diff --git a/vendor/github.com/syndtr/gocapability/LICENSE b/vendor/github.com/syndtr/gocapability/LICENSE deleted file mode 100644 index 80dd96de77f..00000000000 --- a/vendor/github.com/syndtr/gocapability/LICENSE +++ /dev/null @@ -1,24 +0,0 @@ -Copyright 2013 Suryandaru Triandana -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/syndtr/gocapability/capability/capability.go b/vendor/github.com/syndtr/gocapability/capability/capability.go deleted file mode 100644 index 61a90775e59..00000000000 --- a/vendor/github.com/syndtr/gocapability/capability/capability.go +++ /dev/null @@ -1,133 +0,0 @@ -// Copyright (c) 2013, Suryandaru Triandana -// All rights reserved. -// -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Package capability provides utilities for manipulating POSIX capabilities. -package capability - -type Capabilities interface { - // Get check whether a capability present in the given - // capabilities set. The 'which' value should be one of EFFECTIVE, - // PERMITTED, INHERITABLE, BOUNDING or AMBIENT. - Get(which CapType, what Cap) bool - - // Empty check whether all capability bits of the given capabilities - // set are zero. The 'which' value should be one of EFFECTIVE, - // PERMITTED, INHERITABLE, BOUNDING or AMBIENT. - Empty(which CapType) bool - - // Full check whether all capability bits of the given capabilities - // set are one. The 'which' value should be one of EFFECTIVE, - // PERMITTED, INHERITABLE, BOUNDING or AMBIENT. - Full(which CapType) bool - - // Set sets capabilities of the given capabilities sets. The - // 'which' value should be one or combination (OR'ed) of EFFECTIVE, - // PERMITTED, INHERITABLE, BOUNDING or AMBIENT. - Set(which CapType, caps ...Cap) - - // Unset unsets capabilities of the given capabilities sets. The - // 'which' value should be one or combination (OR'ed) of EFFECTIVE, - // PERMITTED, INHERITABLE, BOUNDING or AMBIENT. - Unset(which CapType, caps ...Cap) - - // Fill sets all bits of the given capabilities kind to one. The - // 'kind' value should be one or combination (OR'ed) of CAPS, - // BOUNDS or AMBS. - Fill(kind CapType) - - // Clear sets all bits of the given capabilities kind to zero. The - // 'kind' value should be one or combination (OR'ed) of CAPS, - // BOUNDS or AMBS. - Clear(kind CapType) - - // String return current capabilities state of the given capabilities - // set as string. The 'which' value should be one of EFFECTIVE, - // PERMITTED, INHERITABLE BOUNDING or AMBIENT - StringCap(which CapType) string - - // String return current capabilities state as string. - String() string - - // Load load actual capabilities value. This will overwrite all - // outstanding changes. - Load() error - - // Apply apply the capabilities settings, so all changes will take - // effect. - Apply(kind CapType) error -} - -// NewPid initializes a new Capabilities object for given pid when -// it is nonzero, or for the current process if pid is 0. -// -// Deprecated: Replace with NewPid2. For example, replace: -// -// c, err := NewPid(0) -// if err != nil { -// return err -// } -// -// with: -// -// c, err := NewPid2(0) -// if err != nil { -// return err -// } -// err = c.Load() -// if err != nil { -// return err -// } -func NewPid(pid int) (Capabilities, error) { - c, err := newPid(pid) - if err != nil { - return c, err - } - err = c.Load() - return c, err -} - -// NewPid2 initializes a new Capabilities object for given pid when -// it is nonzero, or for the current process if pid is 0. This -// does not load the process's current capabilities; to do that you -// must call Load explicitly. -func NewPid2(pid int) (Capabilities, error) { - return newPid(pid) -} - -// NewFile initializes a new Capabilities object for given file path. -// -// Deprecated: Replace with NewFile2. For example, replace: -// -// c, err := NewFile(path) -// if err != nil { -// return err -// } -// -// with: -// -// c, err := NewFile2(path) -// if err != nil { -// return err -// } -// err = c.Load() -// if err != nil { -// return err -// } -func NewFile(path string) (Capabilities, error) { - c, err := newFile(path) - if err != nil { - return c, err - } - err = c.Load() - return c, err -} - -// NewFile2 creates a new initialized Capabilities object for given -// file path. This does not load the process's current capabilities; -// to do that you must call Load explicitly. -func NewFile2(path string) (Capabilities, error) { - return newFile(path) -} diff --git a/vendor/github.com/syndtr/gocapability/capability/capability_linux.go b/vendor/github.com/syndtr/gocapability/capability/capability_linux.go deleted file mode 100644 index 1567dc81040..00000000000 --- a/vendor/github.com/syndtr/gocapability/capability/capability_linux.go +++ /dev/null @@ -1,642 +0,0 @@ -// Copyright (c) 2013, Suryandaru Triandana -// All rights reserved. -// -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package capability - -import ( - "bufio" - "errors" - "fmt" - "io" - "os" - "strings" - "syscall" -) - -var errUnknownVers = errors.New("unknown capability version") - -const ( - linuxCapVer1 = 0x19980330 - linuxCapVer2 = 0x20071026 - linuxCapVer3 = 0x20080522 -) - -var ( - capVers uint32 - capLastCap Cap -) - -func init() { - var hdr capHeader - capget(&hdr, nil) - capVers = hdr.version - - if initLastCap() == nil { - CAP_LAST_CAP = capLastCap - if capLastCap > 31 { - capUpperMask = (uint32(1) << (uint(capLastCap) - 31)) - 1 - } else { - capUpperMask = 0 - } - } -} - -func initLastCap() error { - if capLastCap != 0 { - return nil - } - - f, err := os.Open("/proc/sys/kernel/cap_last_cap") - if err != nil { - return err - } - defer f.Close() - - var b []byte = make([]byte, 11) - _, err = f.Read(b) - if err != nil { - return err - } - - fmt.Sscanf(string(b), "%d", &capLastCap) - - return nil -} - -func mkStringCap(c Capabilities, which CapType) (ret string) { - for i, first := Cap(0), true; i <= CAP_LAST_CAP; i++ { - if !c.Get(which, i) { - continue - } - if first { - first = false - } else { - ret += ", " - } - ret += i.String() - } - return -} - -func mkString(c Capabilities, max CapType) (ret string) { - ret = "{" - for i := CapType(1); i <= max; i <<= 1 { - ret += " " + i.String() + "=\"" - if c.Empty(i) { - ret += "empty" - } else if c.Full(i) { - ret += "full" - } else { - ret += c.StringCap(i) - } - ret += "\"" - } - ret += " }" - return -} - -func newPid(pid int) (c Capabilities, err error) { - switch capVers { - case linuxCapVer1: - p := new(capsV1) - p.hdr.version = capVers - p.hdr.pid = int32(pid) - c = p - case linuxCapVer2, linuxCapVer3: - p := new(capsV3) - p.hdr.version = capVers - p.hdr.pid = int32(pid) - c = p - default: - err = errUnknownVers - return - } - return -} - -type capsV1 struct { - hdr capHeader - data capData -} - -func (c *capsV1) Get(which CapType, what Cap) bool { - if what > 32 { - return false - } - - switch which { - case EFFECTIVE: - return (1< 32 { - continue - } - - if which&EFFECTIVE != 0 { - c.data.effective |= 1 << uint(what) - } - if which&PERMITTED != 0 { - c.data.permitted |= 1 << uint(what) - } - if which&INHERITABLE != 0 { - c.data.inheritable |= 1 << uint(what) - } - } -} - -func (c *capsV1) Unset(which CapType, caps ...Cap) { - for _, what := range caps { - if what > 32 { - continue - } - - if which&EFFECTIVE != 0 { - c.data.effective &= ^(1 << uint(what)) - } - if which&PERMITTED != 0 { - c.data.permitted &= ^(1 << uint(what)) - } - if which&INHERITABLE != 0 { - c.data.inheritable &= ^(1 << uint(what)) - } - } -} - -func (c *capsV1) Fill(kind CapType) { - if kind&CAPS == CAPS { - c.data.effective = 0x7fffffff - c.data.permitted = 0x7fffffff - c.data.inheritable = 0 - } -} - -func (c *capsV1) Clear(kind CapType) { - if kind&CAPS == CAPS { - c.data.effective = 0 - c.data.permitted = 0 - c.data.inheritable = 0 - } -} - -func (c *capsV1) StringCap(which CapType) (ret string) { - return mkStringCap(c, which) -} - -func (c *capsV1) String() (ret string) { - return mkString(c, BOUNDING) -} - -func (c *capsV1) Load() (err error) { - return capget(&c.hdr, &c.data) -} - -func (c *capsV1) Apply(kind CapType) error { - if kind&CAPS == CAPS { - return capset(&c.hdr, &c.data) - } - return nil -} - -type capsV3 struct { - hdr capHeader - data [2]capData - bounds [2]uint32 - ambient [2]uint32 -} - -func (c *capsV3) Get(which CapType, what Cap) bool { - var i uint - if what > 31 { - i = uint(what) >> 5 - what %= 32 - } - - switch which { - case EFFECTIVE: - return (1< 31 { - i = uint(what) >> 5 - what %= 32 - } - - if which&EFFECTIVE != 0 { - c.data[i].effective |= 1 << uint(what) - } - if which&PERMITTED != 0 { - c.data[i].permitted |= 1 << uint(what) - } - if which&INHERITABLE != 0 { - c.data[i].inheritable |= 1 << uint(what) - } - if which&BOUNDING != 0 { - c.bounds[i] |= 1 << uint(what) - } - if which&AMBIENT != 0 { - c.ambient[i] |= 1 << uint(what) - } - } -} - -func (c *capsV3) Unset(which CapType, caps ...Cap) { - for _, what := range caps { - var i uint - if what > 31 { - i = uint(what) >> 5 - what %= 32 - } - - if which&EFFECTIVE != 0 { - c.data[i].effective &= ^(1 << uint(what)) - } - if which&PERMITTED != 0 { - c.data[i].permitted &= ^(1 << uint(what)) - } - if which&INHERITABLE != 0 { - c.data[i].inheritable &= ^(1 << uint(what)) - } - if which&BOUNDING != 0 { - c.bounds[i] &= ^(1 << uint(what)) - } - if which&AMBIENT != 0 { - c.ambient[i] &= ^(1 << uint(what)) - } - } -} - -func (c *capsV3) Fill(kind CapType) { - if kind&CAPS == CAPS { - c.data[0].effective = 0xffffffff - c.data[0].permitted = 0xffffffff - c.data[0].inheritable = 0 - c.data[1].effective = 0xffffffff - c.data[1].permitted = 0xffffffff - c.data[1].inheritable = 0 - } - - if kind&BOUNDS == BOUNDS { - c.bounds[0] = 0xffffffff - c.bounds[1] = 0xffffffff - } - if kind&AMBS == AMBS { - c.ambient[0] = 0xffffffff - c.ambient[1] = 0xffffffff - } -} - -func (c *capsV3) Clear(kind CapType) { - if kind&CAPS == CAPS { - c.data[0].effective = 0 - c.data[0].permitted = 0 - c.data[0].inheritable = 0 - c.data[1].effective = 0 - c.data[1].permitted = 0 - c.data[1].inheritable = 0 - } - - if kind&BOUNDS == BOUNDS { - c.bounds[0] = 0 - c.bounds[1] = 0 - } - if kind&AMBS == AMBS { - c.ambient[0] = 0 - c.ambient[1] = 0 - } -} - -func (c *capsV3) StringCap(which CapType) (ret string) { - return mkStringCap(c, which) -} - -func (c *capsV3) String() (ret string) { - return mkString(c, BOUNDING) -} - -func (c *capsV3) Load() (err error) { - err = capget(&c.hdr, &c.data[0]) - if err != nil { - return - } - - var status_path string - - if c.hdr.pid == 0 { - status_path = fmt.Sprintf("/proc/self/status") - } else { - status_path = fmt.Sprintf("/proc/%d/status", c.hdr.pid) - } - - f, err := os.Open(status_path) - if err != nil { - return - } - b := bufio.NewReader(f) - for { - line, e := b.ReadString('\n') - if e != nil { - if e != io.EOF { - err = e - } - break - } - if strings.HasPrefix(line, "CapB") { - fmt.Sscanf(line[4:], "nd: %08x%08x", &c.bounds[1], &c.bounds[0]) - continue - } - if strings.HasPrefix(line, "CapA") { - fmt.Sscanf(line[4:], "mb: %08x%08x", &c.ambient[1], &c.ambient[0]) - continue - } - } - f.Close() - - return -} - -func (c *capsV3) Apply(kind CapType) (err error) { - if kind&BOUNDS == BOUNDS { - var data [2]capData - err = capget(&c.hdr, &data[0]) - if err != nil { - return - } - if (1< 31 { - if c.data.version == 1 { - return false - } - i = uint(what) >> 5 - what %= 32 - } - - switch which { - case EFFECTIVE: - return (1< 31 { - if c.data.version == 1 { - continue - } - i = uint(what) >> 5 - what %= 32 - } - - if which&EFFECTIVE != 0 { - c.data.effective[i] |= 1 << uint(what) - } - if which&PERMITTED != 0 { - c.data.data[i].permitted |= 1 << uint(what) - } - if which&INHERITABLE != 0 { - c.data.data[i].inheritable |= 1 << uint(what) - } - } -} - -func (c *capsFile) Unset(which CapType, caps ...Cap) { - for _, what := range caps { - var i uint - if what > 31 { - if c.data.version == 1 { - continue - } - i = uint(what) >> 5 - what %= 32 - } - - if which&EFFECTIVE != 0 { - c.data.effective[i] &= ^(1 << uint(what)) - } - if which&PERMITTED != 0 { - c.data.data[i].permitted &= ^(1 << uint(what)) - } - if which&INHERITABLE != 0 { - c.data.data[i].inheritable &= ^(1 << uint(what)) - } - } -} - -func (c *capsFile) Fill(kind CapType) { - if kind&CAPS == CAPS { - c.data.effective[0] = 0xffffffff - c.data.data[0].permitted = 0xffffffff - c.data.data[0].inheritable = 0 - if c.data.version == 2 { - c.data.effective[1] = 0xffffffff - c.data.data[1].permitted = 0xffffffff - c.data.data[1].inheritable = 0 - } - } -} - -func (c *capsFile) Clear(kind CapType) { - if kind&CAPS == CAPS { - c.data.effective[0] = 0 - c.data.data[0].permitted = 0 - c.data.data[0].inheritable = 0 - if c.data.version == 2 { - c.data.effective[1] = 0 - c.data.data[1].permitted = 0 - c.data.data[1].inheritable = 0 - } - } -} - -func (c *capsFile) StringCap(which CapType) (ret string) { - return mkStringCap(c, which) -} - -func (c *capsFile) String() (ret string) { - return mkString(c, INHERITABLE) -} - -func (c *capsFile) Load() (err error) { - return getVfsCap(c.path, &c.data) -} - -func (c *capsFile) Apply(kind CapType) (err error) { - if kind&CAPS == CAPS { - return setVfsCap(c.path, &c.data) - } - return -} diff --git a/vendor/github.com/syndtr/gocapability/capability/capability_noop.go b/vendor/github.com/syndtr/gocapability/capability/capability_noop.go deleted file mode 100644 index 9bb3070c5ec..00000000000 --- a/vendor/github.com/syndtr/gocapability/capability/capability_noop.go +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright (c) 2013, Suryandaru Triandana -// All rights reserved. -// -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// +build !linux - -package capability - -import "errors" - -func newPid(pid int) (Capabilities, error) { - return nil, errors.New("not supported") -} - -func newFile(path string) (Capabilities, error) { - return nil, errors.New("not supported") -} diff --git a/vendor/github.com/syndtr/gocapability/capability/enum.go b/vendor/github.com/syndtr/gocapability/capability/enum.go deleted file mode 100644 index ad10785314d..00000000000 --- a/vendor/github.com/syndtr/gocapability/capability/enum.go +++ /dev/null @@ -1,309 +0,0 @@ -// Copyright (c) 2013, Suryandaru Triandana -// All rights reserved. -// -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package capability - -type CapType uint - -func (c CapType) String() string { - switch c { - case EFFECTIVE: - return "effective" - case PERMITTED: - return "permitted" - case INHERITABLE: - return "inheritable" - case BOUNDING: - return "bounding" - case CAPS: - return "caps" - case AMBIENT: - return "ambient" - } - return "unknown" -} - -const ( - EFFECTIVE CapType = 1 << iota - PERMITTED - INHERITABLE - BOUNDING - AMBIENT - - CAPS = EFFECTIVE | PERMITTED | INHERITABLE - BOUNDS = BOUNDING - AMBS = AMBIENT -) - -//go:generate go run enumgen/gen.go -type Cap int - -// POSIX-draft defined capabilities and Linux extensions. -// -// Defined in https://github.com/torvalds/linux/blob/master/include/uapi/linux/capability.h -const ( - // In a system with the [_POSIX_CHOWN_RESTRICTED] option defined, this - // overrides the restriction of changing file ownership and group - // ownership. - CAP_CHOWN = Cap(0) - - // Override all DAC access, including ACL execute access if - // [_POSIX_ACL] is defined. Excluding DAC access covered by - // CAP_LINUX_IMMUTABLE. - CAP_DAC_OVERRIDE = Cap(1) - - // Overrides all DAC restrictions regarding read and search on files - // and directories, including ACL restrictions if [_POSIX_ACL] is - // defined. Excluding DAC access covered by CAP_LINUX_IMMUTABLE. - CAP_DAC_READ_SEARCH = Cap(2) - - // Overrides all restrictions about allowed operations on files, where - // file owner ID must be equal to the user ID, except where CAP_FSETID - // is applicable. It doesn't override MAC and DAC restrictions. - CAP_FOWNER = Cap(3) - - // Overrides the following restrictions that the effective user ID - // shall match the file owner ID when setting the S_ISUID and S_ISGID - // bits on that file; that the effective group ID (or one of the - // supplementary group IDs) shall match the file owner ID when setting - // the S_ISGID bit on that file; that the S_ISUID and S_ISGID bits are - // cleared on successful return from chown(2) (not implemented). - CAP_FSETID = Cap(4) - - // Overrides the restriction that the real or effective user ID of a - // process sending a signal must match the real or effective user ID - // of the process receiving the signal. - CAP_KILL = Cap(5) - - // Allows setgid(2) manipulation - // Allows setgroups(2) - // Allows forged gids on socket credentials passing. - CAP_SETGID = Cap(6) - - // Allows set*uid(2) manipulation (including fsuid). - // Allows forged pids on socket credentials passing. - CAP_SETUID = Cap(7) - - // Linux-specific capabilities - - // Without VFS support for capabilities: - // Transfer any capability in your permitted set to any pid, - // remove any capability in your permitted set from any pid - // With VFS support for capabilities (neither of above, but) - // Add any capability from current's capability bounding set - // to the current process' inheritable set - // Allow taking bits out of capability bounding set - // Allow modification of the securebits for a process - CAP_SETPCAP = Cap(8) - - // Allow modification of S_IMMUTABLE and S_APPEND file attributes - CAP_LINUX_IMMUTABLE = Cap(9) - - // Allows binding to TCP/UDP sockets below 1024 - // Allows binding to ATM VCIs below 32 - CAP_NET_BIND_SERVICE = Cap(10) - - // Allow broadcasting, listen to multicast - CAP_NET_BROADCAST = Cap(11) - - // Allow interface configuration - // Allow administration of IP firewall, masquerading and accounting - // Allow setting debug option on sockets - // Allow modification of routing tables - // Allow setting arbitrary process / process group ownership on - // sockets - // Allow binding to any address for transparent proxying (also via NET_RAW) - // Allow setting TOS (type of service) - // Allow setting promiscuous mode - // Allow clearing driver statistics - // Allow multicasting - // Allow read/write of device-specific registers - // Allow activation of ATM control sockets - CAP_NET_ADMIN = Cap(12) - - // Allow use of RAW sockets - // Allow use of PACKET sockets - // Allow binding to any address for transparent proxying (also via NET_ADMIN) - CAP_NET_RAW = Cap(13) - - // Allow locking of shared memory segments - // Allow mlock and mlockall (which doesn't really have anything to do - // with IPC) - CAP_IPC_LOCK = Cap(14) - - // Override IPC ownership checks - CAP_IPC_OWNER = Cap(15) - - // Insert and remove kernel modules - modify kernel without limit - CAP_SYS_MODULE = Cap(16) - - // Allow ioperm/iopl access - // Allow sending USB messages to any device via /proc/bus/usb - CAP_SYS_RAWIO = Cap(17) - - // Allow use of chroot() - CAP_SYS_CHROOT = Cap(18) - - // Allow ptrace() of any process - CAP_SYS_PTRACE = Cap(19) - - // Allow configuration of process accounting - CAP_SYS_PACCT = Cap(20) - - // Allow configuration of the secure attention key - // Allow administration of the random device - // Allow examination and configuration of disk quotas - // Allow setting the domainname - // Allow setting the hostname - // Allow calling bdflush() - // Allow mount() and umount(), setting up new smb connection - // Allow some autofs root ioctls - // Allow nfsservctl - // Allow VM86_REQUEST_IRQ - // Allow to read/write pci config on alpha - // Allow irix_prctl on mips (setstacksize) - // Allow flushing all cache on m68k (sys_cacheflush) - // Allow removing semaphores - // Used instead of CAP_CHOWN to "chown" IPC message queues, semaphores - // and shared memory - // Allow locking/unlocking of shared memory segment - // Allow turning swap on/off - // Allow forged pids on socket credentials passing - // Allow setting readahead and flushing buffers on block devices - // Allow setting geometry in floppy driver - // Allow turning DMA on/off in xd driver - // Allow administration of md devices (mostly the above, but some - // extra ioctls) - // Allow tuning the ide driver - // Allow access to the nvram device - // Allow administration of apm_bios, serial and bttv (TV) device - // Allow manufacturer commands in isdn CAPI support driver - // Allow reading non-standardized portions of pci configuration space - // Allow DDI debug ioctl on sbpcd driver - // Allow setting up serial ports - // Allow sending raw qic-117 commands - // Allow enabling/disabling tagged queuing on SCSI controllers and sending - // arbitrary SCSI commands - // Allow setting encryption key on loopback filesystem - // Allow setting zone reclaim policy - // Allow everything under CAP_BPF and CAP_PERFMON for backward compatibility - CAP_SYS_ADMIN = Cap(21) - - // Allow use of reboot() - CAP_SYS_BOOT = Cap(22) - - // Allow raising priority and setting priority on other (different - // UID) processes - // Allow use of FIFO and round-robin (realtime) scheduling on own - // processes and setting the scheduling algorithm used by another - // process. - // Allow setting cpu affinity on other processes - CAP_SYS_NICE = Cap(23) - - // Override resource limits. Set resource limits. - // Override quota limits. - // Override reserved space on ext2 filesystem - // Modify data journaling mode on ext3 filesystem (uses journaling - // resources) - // NOTE: ext2 honors fsuid when checking for resource overrides, so - // you can override using fsuid too - // Override size restrictions on IPC message queues - // Allow more than 64hz interrupts from the real-time clock - // Override max number of consoles on console allocation - // Override max number of keymaps - // Control memory reclaim behavior - CAP_SYS_RESOURCE = Cap(24) - - // Allow manipulation of system clock - // Allow irix_stime on mips - // Allow setting the real-time clock - CAP_SYS_TIME = Cap(25) - - // Allow configuration of tty devices - // Allow vhangup() of tty - CAP_SYS_TTY_CONFIG = Cap(26) - - // Allow the privileged aspects of mknod() - CAP_MKNOD = Cap(27) - - // Allow taking of leases on files - CAP_LEASE = Cap(28) - - CAP_AUDIT_WRITE = Cap(29) - CAP_AUDIT_CONTROL = Cap(30) - CAP_SETFCAP = Cap(31) - - // Override MAC access. - // The base kernel enforces no MAC policy. - // An LSM may enforce a MAC policy, and if it does and it chooses - // to implement capability based overrides of that policy, this is - // the capability it should use to do so. - CAP_MAC_OVERRIDE = Cap(32) - - // Allow MAC configuration or state changes. - // The base kernel requires no MAC configuration. - // An LSM may enforce a MAC policy, and if it does and it chooses - // to implement capability based checks on modifications to that - // policy or the data required to maintain it, this is the - // capability it should use to do so. - CAP_MAC_ADMIN = Cap(33) - - // Allow configuring the kernel's syslog (printk behaviour) - CAP_SYSLOG = Cap(34) - - // Allow triggering something that will wake the system - CAP_WAKE_ALARM = Cap(35) - - // Allow preventing system suspends - CAP_BLOCK_SUSPEND = Cap(36) - - // Allow reading the audit log via multicast netlink socket - CAP_AUDIT_READ = Cap(37) - - // Allow system performance and observability privileged operations - // using perf_events, i915_perf and other kernel subsystems - CAP_PERFMON = Cap(38) - - // CAP_BPF allows the following BPF operations: - // - Creating all types of BPF maps - // - Advanced verifier features - // - Indirect variable access - // - Bounded loops - // - BPF to BPF function calls - // - Scalar precision tracking - // - Larger complexity limits - // - Dead code elimination - // - And potentially other features - // - Loading BPF Type Format (BTF) data - // - Retrieve xlated and JITed code of BPF programs - // - Use bpf_spin_lock() helper - // - // CAP_PERFMON relaxes the verifier checks further: - // - BPF progs can use of pointer-to-integer conversions - // - speculation attack hardening measures are bypassed - // - bpf_probe_read to read arbitrary kernel memory is allowed - // - bpf_trace_printk to print kernel memory is allowed - // - // CAP_SYS_ADMIN is required to use bpf_probe_write_user. - // - // CAP_SYS_ADMIN is required to iterate system wide loaded - // programs, maps, links, BTFs and convert their IDs to file descriptors. - // - // CAP_PERFMON and CAP_BPF are required to load tracing programs. - // CAP_NET_ADMIN and CAP_BPF are required to load networking programs. - CAP_BPF = Cap(39) - - // Allow checkpoint/restore related operations. - // Introduced in kernel 5.9 - CAP_CHECKPOINT_RESTORE = Cap(40) -) - -var ( - // Highest valid capability of the running kernel. - CAP_LAST_CAP = Cap(63) - - capUpperMask = ^uint32(0) -) diff --git a/vendor/github.com/syndtr/gocapability/capability/enum_gen.go b/vendor/github.com/syndtr/gocapability/capability/enum_gen.go deleted file mode 100644 index 2ff9bf4d887..00000000000 --- a/vendor/github.com/syndtr/gocapability/capability/enum_gen.go +++ /dev/null @@ -1,138 +0,0 @@ -// generated file; DO NOT EDIT - use go generate in directory with source - -package capability - -func (c Cap) String() string { - switch c { - case CAP_CHOWN: - return "chown" - case CAP_DAC_OVERRIDE: - return "dac_override" - case CAP_DAC_READ_SEARCH: - return "dac_read_search" - case CAP_FOWNER: - return "fowner" - case CAP_FSETID: - return "fsetid" - case CAP_KILL: - return "kill" - case CAP_SETGID: - return "setgid" - case CAP_SETUID: - return "setuid" - case CAP_SETPCAP: - return "setpcap" - case CAP_LINUX_IMMUTABLE: - return "linux_immutable" - case CAP_NET_BIND_SERVICE: - return "net_bind_service" - case CAP_NET_BROADCAST: - return "net_broadcast" - case CAP_NET_ADMIN: - return "net_admin" - case CAP_NET_RAW: - return "net_raw" - case CAP_IPC_LOCK: - return "ipc_lock" - case CAP_IPC_OWNER: - return "ipc_owner" - case CAP_SYS_MODULE: - return "sys_module" - case CAP_SYS_RAWIO: - return "sys_rawio" - case CAP_SYS_CHROOT: - return "sys_chroot" - case CAP_SYS_PTRACE: - return "sys_ptrace" - case CAP_SYS_PACCT: - return "sys_pacct" - case CAP_SYS_ADMIN: - return "sys_admin" - case CAP_SYS_BOOT: - return "sys_boot" - case CAP_SYS_NICE: - return "sys_nice" - case CAP_SYS_RESOURCE: - return "sys_resource" - case CAP_SYS_TIME: - return "sys_time" - case CAP_SYS_TTY_CONFIG: - return "sys_tty_config" - case CAP_MKNOD: - return "mknod" - case CAP_LEASE: - return "lease" - case CAP_AUDIT_WRITE: - return "audit_write" - case CAP_AUDIT_CONTROL: - return "audit_control" - case CAP_SETFCAP: - return "setfcap" - case CAP_MAC_OVERRIDE: - return "mac_override" - case CAP_MAC_ADMIN: - return "mac_admin" - case CAP_SYSLOG: - return "syslog" - case CAP_WAKE_ALARM: - return "wake_alarm" - case CAP_BLOCK_SUSPEND: - return "block_suspend" - case CAP_AUDIT_READ: - return "audit_read" - case CAP_PERFMON: - return "perfmon" - case CAP_BPF: - return "bpf" - case CAP_CHECKPOINT_RESTORE: - return "checkpoint_restore" - } - return "unknown" -} - -// List returns list of all supported capabilities -func List() []Cap { - return []Cap{ - CAP_CHOWN, - CAP_DAC_OVERRIDE, - CAP_DAC_READ_SEARCH, - CAP_FOWNER, - CAP_FSETID, - CAP_KILL, - CAP_SETGID, - CAP_SETUID, - CAP_SETPCAP, - CAP_LINUX_IMMUTABLE, - CAP_NET_BIND_SERVICE, - CAP_NET_BROADCAST, - CAP_NET_ADMIN, - CAP_NET_RAW, - CAP_IPC_LOCK, - CAP_IPC_OWNER, - CAP_SYS_MODULE, - CAP_SYS_RAWIO, - CAP_SYS_CHROOT, - CAP_SYS_PTRACE, - CAP_SYS_PACCT, - CAP_SYS_ADMIN, - CAP_SYS_BOOT, - CAP_SYS_NICE, - CAP_SYS_RESOURCE, - CAP_SYS_TIME, - CAP_SYS_TTY_CONFIG, - CAP_MKNOD, - CAP_LEASE, - CAP_AUDIT_WRITE, - CAP_AUDIT_CONTROL, - CAP_SETFCAP, - CAP_MAC_OVERRIDE, - CAP_MAC_ADMIN, - CAP_SYSLOG, - CAP_WAKE_ALARM, - CAP_BLOCK_SUSPEND, - CAP_AUDIT_READ, - CAP_PERFMON, - CAP_BPF, - CAP_CHECKPOINT_RESTORE, - } -} diff --git a/vendor/github.com/syndtr/gocapability/capability/syscall_linux.go b/vendor/github.com/syndtr/gocapability/capability/syscall_linux.go deleted file mode 100644 index 3d2bf6927f3..00000000000 --- a/vendor/github.com/syndtr/gocapability/capability/syscall_linux.go +++ /dev/null @@ -1,154 +0,0 @@ -// Copyright (c) 2013, Suryandaru Triandana -// All rights reserved. -// -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package capability - -import ( - "syscall" - "unsafe" -) - -type capHeader struct { - version uint32 - pid int32 -} - -type capData struct { - effective uint32 - permitted uint32 - inheritable uint32 -} - -func capget(hdr *capHeader, data *capData) (err error) { - _, _, e1 := syscall.Syscall(syscall.SYS_CAPGET, uintptr(unsafe.Pointer(hdr)), uintptr(unsafe.Pointer(data)), 0) - if e1 != 0 { - err = e1 - } - return -} - -func capset(hdr *capHeader, data *capData) (err error) { - _, _, e1 := syscall.Syscall(syscall.SYS_CAPSET, uintptr(unsafe.Pointer(hdr)), uintptr(unsafe.Pointer(data)), 0) - if e1 != 0 { - err = e1 - } - return -} - -// not yet in syscall -const ( - pr_CAP_AMBIENT = 47 - pr_CAP_AMBIENT_IS_SET = uintptr(1) - pr_CAP_AMBIENT_RAISE = uintptr(2) - pr_CAP_AMBIENT_LOWER = uintptr(3) - pr_CAP_AMBIENT_CLEAR_ALL = uintptr(4) -) - -func prctl(option int, arg2, arg3, arg4, arg5 uintptr) (err error) { - _, _, e1 := syscall.Syscall6(syscall.SYS_PRCTL, uintptr(option), arg2, arg3, arg4, arg5, 0) - if e1 != 0 { - err = e1 - } - return -} - -const ( - vfsXattrName = "security.capability" - - vfsCapVerMask = 0xff000000 - vfsCapVer1 = 0x01000000 - vfsCapVer2 = 0x02000000 - - vfsCapFlagMask = ^vfsCapVerMask - vfsCapFlageffective = 0x000001 - - vfscapDataSizeV1 = 4 * (1 + 2*1) - vfscapDataSizeV2 = 4 * (1 + 2*2) -) - -type vfscapData struct { - magic uint32 - data [2]struct { - permitted uint32 - inheritable uint32 - } - effective [2]uint32 - version int8 -} - -var ( - _vfsXattrName *byte -) - -func init() { - _vfsXattrName, _ = syscall.BytePtrFromString(vfsXattrName) -} - -func getVfsCap(path string, dest *vfscapData) (err error) { - var _p0 *byte - _p0, err = syscall.BytePtrFromString(path) - if err != nil { - return - } - r0, _, e1 := syscall.Syscall6(syscall.SYS_GETXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_vfsXattrName)), uintptr(unsafe.Pointer(dest)), vfscapDataSizeV2, 0, 0) - if e1 != 0 { - if e1 == syscall.ENODATA { - dest.version = 2 - return - } - err = e1 - } - switch dest.magic & vfsCapVerMask { - case vfsCapVer1: - dest.version = 1 - if r0 != vfscapDataSizeV1 { - return syscall.EINVAL - } - dest.data[1].permitted = 0 - dest.data[1].inheritable = 0 - case vfsCapVer2: - dest.version = 2 - if r0 != vfscapDataSizeV2 { - return syscall.EINVAL - } - default: - return syscall.EINVAL - } - if dest.magic&vfsCapFlageffective != 0 { - dest.effective[0] = dest.data[0].permitted | dest.data[0].inheritable - dest.effective[1] = dest.data[1].permitted | dest.data[1].inheritable - } else { - dest.effective[0] = 0 - dest.effective[1] = 0 - } - return -} - -func setVfsCap(path string, data *vfscapData) (err error) { - var _p0 *byte - _p0, err = syscall.BytePtrFromString(path) - if err != nil { - return - } - var size uintptr - if data.version == 1 { - data.magic = vfsCapVer1 - size = vfscapDataSizeV1 - } else if data.version == 2 { - data.magic = vfsCapVer2 - if data.effective[0] != 0 || data.effective[1] != 0 { - data.magic |= vfsCapFlageffective - } - size = vfscapDataSizeV2 - } else { - return syscall.EINVAL - } - _, _, e1 := syscall.Syscall6(syscall.SYS_SETXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_vfsXattrName)), uintptr(unsafe.Pointer(data)), size, 0, 0) - if e1 != 0 { - err = e1 - } - return -} diff --git a/vendor/golang.org/x/net/bpf/asm.go b/vendor/golang.org/x/net/bpf/asm.go deleted file mode 100644 index 15e21b18122..00000000000 --- a/vendor/golang.org/x/net/bpf/asm.go +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright 2016 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package bpf - -import "fmt" - -// Assemble converts insts into raw instructions suitable for loading -// into a BPF virtual machine. -// -// Currently, no optimization is attempted, the assembled program flow -// is exactly as provided. -func Assemble(insts []Instruction) ([]RawInstruction, error) { - ret := make([]RawInstruction, len(insts)) - var err error - for i, inst := range insts { - ret[i], err = inst.Assemble() - if err != nil { - return nil, fmt.Errorf("assembling instruction %d: %s", i+1, err) - } - } - return ret, nil -} - -// Disassemble attempts to parse raw back into -// Instructions. Unrecognized RawInstructions are assumed to be an -// extension not implemented by this package, and are passed through -// unchanged to the output. The allDecoded value reports whether insts -// contains no RawInstructions. -func Disassemble(raw []RawInstruction) (insts []Instruction, allDecoded bool) { - insts = make([]Instruction, len(raw)) - allDecoded = true - for i, r := range raw { - insts[i] = r.Disassemble() - if _, ok := insts[i].(RawInstruction); ok { - allDecoded = false - } - } - return insts, allDecoded -} diff --git a/vendor/golang.org/x/net/bpf/constants.go b/vendor/golang.org/x/net/bpf/constants.go deleted file mode 100644 index 12f3ee835af..00000000000 --- a/vendor/golang.org/x/net/bpf/constants.go +++ /dev/null @@ -1,222 +0,0 @@ -// Copyright 2016 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package bpf - -// A Register is a register of the BPF virtual machine. -type Register uint16 - -const ( - // RegA is the accumulator register. RegA is always the - // destination register of ALU operations. - RegA Register = iota - // RegX is the indirection register, used by LoadIndirect - // operations. - RegX -) - -// An ALUOp is an arithmetic or logic operation. -type ALUOp uint16 - -// ALU binary operation types. -const ( - ALUOpAdd ALUOp = iota << 4 - ALUOpSub - ALUOpMul - ALUOpDiv - ALUOpOr - ALUOpAnd - ALUOpShiftLeft - ALUOpShiftRight - aluOpNeg // Not exported because it's the only unary ALU operation, and gets its own instruction type. - ALUOpMod - ALUOpXor -) - -// A JumpTest is a comparison operator used in conditional jumps. -type JumpTest uint16 - -// Supported operators for conditional jumps. -// K can be RegX for JumpIfX -const ( - // K == A - JumpEqual JumpTest = iota - // K != A - JumpNotEqual - // K > A - JumpGreaterThan - // K < A - JumpLessThan - // K >= A - JumpGreaterOrEqual - // K <= A - JumpLessOrEqual - // K & A != 0 - JumpBitsSet - // K & A == 0 - JumpBitsNotSet -) - -// An Extension is a function call provided by the kernel that -// performs advanced operations that are expensive or impossible -// within the BPF virtual machine. -// -// Extensions are only implemented by the Linux kernel. -// -// TODO: should we prune this list? Some of these extensions seem -// either broken or near-impossible to use correctly, whereas other -// (len, random, ifindex) are quite useful. -type Extension int - -// Extension functions available in the Linux kernel. -const ( - // extOffset is the negative maximum number of instructions used - // to load instructions by overloading the K argument. - extOffset = -0x1000 - // ExtLen returns the length of the packet. - ExtLen Extension = 1 - // ExtProto returns the packet's L3 protocol type. - ExtProto Extension = 0 - // ExtType returns the packet's type (skb->pkt_type in the kernel) - // - // TODO: better documentation. How nice an API do we want to - // provide for these esoteric extensions? - ExtType Extension = 4 - // ExtPayloadOffset returns the offset of the packet payload, or - // the first protocol header that the kernel does not know how to - // parse. - ExtPayloadOffset Extension = 52 - // ExtInterfaceIndex returns the index of the interface on which - // the packet was received. - ExtInterfaceIndex Extension = 8 - // ExtNetlinkAttr returns the netlink attribute of type X at - // offset A. - ExtNetlinkAttr Extension = 12 - // ExtNetlinkAttrNested returns the nested netlink attribute of - // type X at offset A. - ExtNetlinkAttrNested Extension = 16 - // ExtMark returns the packet's mark value. - ExtMark Extension = 20 - // ExtQueue returns the packet's assigned hardware queue. - ExtQueue Extension = 24 - // ExtLinkLayerType returns the packet's hardware address type - // (e.g. Ethernet, Infiniband). - ExtLinkLayerType Extension = 28 - // ExtRXHash returns the packets receive hash. - // - // TODO: figure out what this rxhash actually is. - ExtRXHash Extension = 32 - // ExtCPUID returns the ID of the CPU processing the current - // packet. - ExtCPUID Extension = 36 - // ExtVLANTag returns the packet's VLAN tag. - ExtVLANTag Extension = 44 - // ExtVLANTagPresent returns non-zero if the packet has a VLAN - // tag. - // - // TODO: I think this might be a lie: it reads bit 0x1000 of the - // VLAN header, which changed meaning in recent revisions of the - // spec - this extension may now return meaningless information. - ExtVLANTagPresent Extension = 48 - // ExtVLANProto returns 0x8100 if the frame has a VLAN header, - // 0x88a8 if the frame has a "Q-in-Q" double VLAN header, or some - // other value if no VLAN information is present. - ExtVLANProto Extension = 60 - // ExtRand returns a uniformly random uint32. - ExtRand Extension = 56 -) - -// The following gives names to various bit patterns used in opcode construction. - -const ( - opMaskCls uint16 = 0x7 - // opClsLoad masks - opMaskLoadDest = 0x01 - opMaskLoadWidth = 0x18 - opMaskLoadMode = 0xe0 - // opClsALU & opClsJump - opMaskOperand = 0x08 - opMaskOperator = 0xf0 -) - -const ( - // +---------------+-----------------+---+---+---+ - // | AddrMode (3b) | LoadWidth (2b) | 0 | 0 | 0 | - // +---------------+-----------------+---+---+---+ - opClsLoadA uint16 = iota - // +---------------+-----------------+---+---+---+ - // | AddrMode (3b) | LoadWidth (2b) | 0 | 0 | 1 | - // +---------------+-----------------+---+---+---+ - opClsLoadX - // +---+---+---+---+---+---+---+---+ - // | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | - // +---+---+---+---+---+---+---+---+ - opClsStoreA - // +---+---+---+---+---+---+---+---+ - // | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | - // +---+---+---+---+---+---+---+---+ - opClsStoreX - // +---------------+-----------------+---+---+---+ - // | Operator (4b) | OperandSrc (1b) | 1 | 0 | 0 | - // +---------------+-----------------+---+---+---+ - opClsALU - // +-----------------------------+---+---+---+---+ - // | TestOperator (4b) | 0 | 1 | 0 | 1 | - // +-----------------------------+---+---+---+---+ - opClsJump - // +---+-------------------------+---+---+---+---+ - // | 0 | 0 | 0 | RetSrc (1b) | 0 | 1 | 1 | 0 | - // +---+-------------------------+---+---+---+---+ - opClsReturn - // +---+-------------------------+---+---+---+---+ - // | 0 | 0 | 0 | TXAorTAX (1b) | 0 | 1 | 1 | 1 | - // +---+-------------------------+---+---+---+---+ - opClsMisc -) - -const ( - opAddrModeImmediate uint16 = iota << 5 - opAddrModeAbsolute - opAddrModeIndirect - opAddrModeScratch - opAddrModePacketLen // actually an extension, not an addressing mode. - opAddrModeMemShift -) - -const ( - opLoadWidth4 uint16 = iota << 3 - opLoadWidth2 - opLoadWidth1 -) - -// Operand for ALU and Jump instructions -type opOperand uint16 - -// Supported operand sources. -const ( - opOperandConstant opOperand = iota << 3 - opOperandX -) - -// An jumpOp is a conditional jump condition. -type jumpOp uint16 - -// Supported jump conditions. -const ( - opJumpAlways jumpOp = iota << 4 - opJumpEqual - opJumpGT - opJumpGE - opJumpSet -) - -const ( - opRetSrcConstant uint16 = iota << 4 - opRetSrcA -) - -const ( - opMiscTAX = 0x00 - opMiscTXA = 0x80 -) diff --git a/vendor/golang.org/x/net/bpf/doc.go b/vendor/golang.org/x/net/bpf/doc.go deleted file mode 100644 index 04ec1c8ab52..00000000000 --- a/vendor/golang.org/x/net/bpf/doc.go +++ /dev/null @@ -1,80 +0,0 @@ -// Copyright 2016 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -/* -Package bpf implements marshaling and unmarshaling of programs for the -Berkeley Packet Filter virtual machine, and provides a Go implementation -of the virtual machine. - -BPF's main use is to specify a packet filter for network taps, so that -the kernel doesn't have to expensively copy every packet it sees to -userspace. However, it's been repurposed to other areas where running -user code in-kernel is needed. For example, Linux's seccomp uses BPF -to apply security policies to system calls. For simplicity, this -documentation refers only to packets, but other uses of BPF have their -own data payloads. - -BPF programs run in a restricted virtual machine. It has almost no -access to kernel functions, and while conditional branches are -allowed, they can only jump forwards, to guarantee that there are no -infinite loops. - -# The virtual machine - -The BPF VM is an accumulator machine. Its main register, called -register A, is an implicit source and destination in all arithmetic -and logic operations. The machine also has 16 scratch registers for -temporary storage, and an indirection register (register X) for -indirect memory access. All registers are 32 bits wide. - -Each run of a BPF program is given one packet, which is placed in the -VM's read-only "main memory". LoadAbsolute and LoadIndirect -instructions can fetch up to 32 bits at a time into register A for -examination. - -The goal of a BPF program is to produce and return a verdict (uint32), -which tells the kernel what to do with the packet. In the context of -packet filtering, the returned value is the number of bytes of the -packet to forward to userspace, or 0 to ignore the packet. Other -contexts like seccomp define their own return values. - -In order to simplify programs, attempts to read past the end of the -packet terminate the program execution with a verdict of 0 (ignore -packet). This means that the vast majority of BPF programs don't need -to do any explicit bounds checking. - -In addition to the bytes of the packet, some BPF programs have access -to extensions, which are essentially calls to kernel utility -functions. Currently, the only extensions supported by this package -are the Linux packet filter extensions. - -# Examples - -This packet filter selects all ARP packets. - - bpf.Assemble([]bpf.Instruction{ - // Load "EtherType" field from the ethernet header. - bpf.LoadAbsolute{Off: 12, Size: 2}, - // Skip over the next instruction if EtherType is not ARP. - bpf.JumpIf{Cond: bpf.JumpNotEqual, Val: 0x0806, SkipTrue: 1}, - // Verdict is "send up to 4k of the packet to userspace." - bpf.RetConstant{Val: 4096}, - // Verdict is "ignore packet." - bpf.RetConstant{Val: 0}, - }) - -This packet filter captures a random 1% sample of traffic. - - bpf.Assemble([]bpf.Instruction{ - // Get a 32-bit random number from the Linux kernel. - bpf.LoadExtension{Num: bpf.ExtRand}, - // 1% dice roll? - bpf.JumpIf{Cond: bpf.JumpLessThan, Val: 2^32/100, SkipFalse: 1}, - // Capture. - bpf.RetConstant{Val: 4096}, - // Ignore. - bpf.RetConstant{Val: 0}, - }) -*/ -package bpf // import "golang.org/x/net/bpf" diff --git a/vendor/golang.org/x/net/bpf/instructions.go b/vendor/golang.org/x/net/bpf/instructions.go deleted file mode 100644 index 3cffcaa014e..00000000000 --- a/vendor/golang.org/x/net/bpf/instructions.go +++ /dev/null @@ -1,726 +0,0 @@ -// Copyright 2016 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package bpf - -import "fmt" - -// An Instruction is one instruction executed by the BPF virtual -// machine. -type Instruction interface { - // Assemble assembles the Instruction into a RawInstruction. - Assemble() (RawInstruction, error) -} - -// A RawInstruction is a raw BPF virtual machine instruction. -type RawInstruction struct { - // Operation to execute. - Op uint16 - // For conditional jump instructions, the number of instructions - // to skip if the condition is true/false. - Jt uint8 - Jf uint8 - // Constant parameter. The meaning depends on the Op. - K uint32 -} - -// Assemble implements the Instruction Assemble method. -func (ri RawInstruction) Assemble() (RawInstruction, error) { return ri, nil } - -// Disassemble parses ri into an Instruction and returns it. If ri is -// not recognized by this package, ri itself is returned. -func (ri RawInstruction) Disassemble() Instruction { - switch ri.Op & opMaskCls { - case opClsLoadA, opClsLoadX: - reg := Register(ri.Op & opMaskLoadDest) - sz := 0 - switch ri.Op & opMaskLoadWidth { - case opLoadWidth4: - sz = 4 - case opLoadWidth2: - sz = 2 - case opLoadWidth1: - sz = 1 - default: - return ri - } - switch ri.Op & opMaskLoadMode { - case opAddrModeImmediate: - if sz != 4 { - return ri - } - return LoadConstant{Dst: reg, Val: ri.K} - case opAddrModeScratch: - if sz != 4 || ri.K > 15 { - return ri - } - return LoadScratch{Dst: reg, N: int(ri.K)} - case opAddrModeAbsolute: - if ri.K > extOffset+0xffffffff { - return LoadExtension{Num: Extension(-extOffset + ri.K)} - } - return LoadAbsolute{Size: sz, Off: ri.K} - case opAddrModeIndirect: - return LoadIndirect{Size: sz, Off: ri.K} - case opAddrModePacketLen: - if sz != 4 { - return ri - } - return LoadExtension{Num: ExtLen} - case opAddrModeMemShift: - return LoadMemShift{Off: ri.K} - default: - return ri - } - - case opClsStoreA: - if ri.Op != opClsStoreA || ri.K > 15 { - return ri - } - return StoreScratch{Src: RegA, N: int(ri.K)} - - case opClsStoreX: - if ri.Op != opClsStoreX || ri.K > 15 { - return ri - } - return StoreScratch{Src: RegX, N: int(ri.K)} - - case opClsALU: - switch op := ALUOp(ri.Op & opMaskOperator); op { - case ALUOpAdd, ALUOpSub, ALUOpMul, ALUOpDiv, ALUOpOr, ALUOpAnd, ALUOpShiftLeft, ALUOpShiftRight, ALUOpMod, ALUOpXor: - switch operand := opOperand(ri.Op & opMaskOperand); operand { - case opOperandX: - return ALUOpX{Op: op} - case opOperandConstant: - return ALUOpConstant{Op: op, Val: ri.K} - default: - return ri - } - case aluOpNeg: - return NegateA{} - default: - return ri - } - - case opClsJump: - switch op := jumpOp(ri.Op & opMaskOperator); op { - case opJumpAlways: - return Jump{Skip: ri.K} - case opJumpEqual, opJumpGT, opJumpGE, opJumpSet: - cond, skipTrue, skipFalse := jumpOpToTest(op, ri.Jt, ri.Jf) - switch operand := opOperand(ri.Op & opMaskOperand); operand { - case opOperandX: - return JumpIfX{Cond: cond, SkipTrue: skipTrue, SkipFalse: skipFalse} - case opOperandConstant: - return JumpIf{Cond: cond, Val: ri.K, SkipTrue: skipTrue, SkipFalse: skipFalse} - default: - return ri - } - default: - return ri - } - - case opClsReturn: - switch ri.Op { - case opClsReturn | opRetSrcA: - return RetA{} - case opClsReturn | opRetSrcConstant: - return RetConstant{Val: ri.K} - default: - return ri - } - - case opClsMisc: - switch ri.Op { - case opClsMisc | opMiscTAX: - return TAX{} - case opClsMisc | opMiscTXA: - return TXA{} - default: - return ri - } - - default: - panic("unreachable") // switch is exhaustive on the bit pattern - } -} - -func jumpOpToTest(op jumpOp, skipTrue uint8, skipFalse uint8) (JumpTest, uint8, uint8) { - var test JumpTest - - // Decode "fake" jump conditions that don't appear in machine code - // Ensures the Assemble -> Disassemble stage recreates the same instructions - // See https://github.com/golang/go/issues/18470 - if skipTrue == 0 { - switch op { - case opJumpEqual: - test = JumpNotEqual - case opJumpGT: - test = JumpLessOrEqual - case opJumpGE: - test = JumpLessThan - case opJumpSet: - test = JumpBitsNotSet - } - - return test, skipFalse, 0 - } - - switch op { - case opJumpEqual: - test = JumpEqual - case opJumpGT: - test = JumpGreaterThan - case opJumpGE: - test = JumpGreaterOrEqual - case opJumpSet: - test = JumpBitsSet - } - - return test, skipTrue, skipFalse -} - -// LoadConstant loads Val into register Dst. -type LoadConstant struct { - Dst Register - Val uint32 -} - -// Assemble implements the Instruction Assemble method. -func (a LoadConstant) Assemble() (RawInstruction, error) { - return assembleLoad(a.Dst, 4, opAddrModeImmediate, a.Val) -} - -// String returns the instruction in assembler notation. -func (a LoadConstant) String() string { - switch a.Dst { - case RegA: - return fmt.Sprintf("ld #%d", a.Val) - case RegX: - return fmt.Sprintf("ldx #%d", a.Val) - default: - return fmt.Sprintf("unknown instruction: %#v", a) - } -} - -// LoadScratch loads scratch[N] into register Dst. -type LoadScratch struct { - Dst Register - N int // 0-15 -} - -// Assemble implements the Instruction Assemble method. -func (a LoadScratch) Assemble() (RawInstruction, error) { - if a.N < 0 || a.N > 15 { - return RawInstruction{}, fmt.Errorf("invalid scratch slot %d", a.N) - } - return assembleLoad(a.Dst, 4, opAddrModeScratch, uint32(a.N)) -} - -// String returns the instruction in assembler notation. -func (a LoadScratch) String() string { - switch a.Dst { - case RegA: - return fmt.Sprintf("ld M[%d]", a.N) - case RegX: - return fmt.Sprintf("ldx M[%d]", a.N) - default: - return fmt.Sprintf("unknown instruction: %#v", a) - } -} - -// LoadAbsolute loads packet[Off:Off+Size] as an integer value into -// register A. -type LoadAbsolute struct { - Off uint32 - Size int // 1, 2 or 4 -} - -// Assemble implements the Instruction Assemble method. -func (a LoadAbsolute) Assemble() (RawInstruction, error) { - return assembleLoad(RegA, a.Size, opAddrModeAbsolute, a.Off) -} - -// String returns the instruction in assembler notation. -func (a LoadAbsolute) String() string { - switch a.Size { - case 1: // byte - return fmt.Sprintf("ldb [%d]", a.Off) - case 2: // half word - return fmt.Sprintf("ldh [%d]", a.Off) - case 4: // word - if a.Off > extOffset+0xffffffff { - return LoadExtension{Num: Extension(a.Off + 0x1000)}.String() - } - return fmt.Sprintf("ld [%d]", a.Off) - default: - return fmt.Sprintf("unknown instruction: %#v", a) - } -} - -// LoadIndirect loads packet[X+Off:X+Off+Size] as an integer value -// into register A. -type LoadIndirect struct { - Off uint32 - Size int // 1, 2 or 4 -} - -// Assemble implements the Instruction Assemble method. -func (a LoadIndirect) Assemble() (RawInstruction, error) { - return assembleLoad(RegA, a.Size, opAddrModeIndirect, a.Off) -} - -// String returns the instruction in assembler notation. -func (a LoadIndirect) String() string { - switch a.Size { - case 1: // byte - return fmt.Sprintf("ldb [x + %d]", a.Off) - case 2: // half word - return fmt.Sprintf("ldh [x + %d]", a.Off) - case 4: // word - return fmt.Sprintf("ld [x + %d]", a.Off) - default: - return fmt.Sprintf("unknown instruction: %#v", a) - } -} - -// LoadMemShift multiplies the first 4 bits of the byte at packet[Off] -// by 4 and stores the result in register X. -// -// This instruction is mainly useful to load into X the length of an -// IPv4 packet header in a single instruction, rather than have to do -// the arithmetic on the header's first byte by hand. -type LoadMemShift struct { - Off uint32 -} - -// Assemble implements the Instruction Assemble method. -func (a LoadMemShift) Assemble() (RawInstruction, error) { - return assembleLoad(RegX, 1, opAddrModeMemShift, a.Off) -} - -// String returns the instruction in assembler notation. -func (a LoadMemShift) String() string { - return fmt.Sprintf("ldx 4*([%d]&0xf)", a.Off) -} - -// LoadExtension invokes a linux-specific extension and stores the -// result in register A. -type LoadExtension struct { - Num Extension -} - -// Assemble implements the Instruction Assemble method. -func (a LoadExtension) Assemble() (RawInstruction, error) { - if a.Num == ExtLen { - return assembleLoad(RegA, 4, opAddrModePacketLen, 0) - } - return assembleLoad(RegA, 4, opAddrModeAbsolute, uint32(extOffset+a.Num)) -} - -// String returns the instruction in assembler notation. -func (a LoadExtension) String() string { - switch a.Num { - case ExtLen: - return "ld #len" - case ExtProto: - return "ld #proto" - case ExtType: - return "ld #type" - case ExtPayloadOffset: - return "ld #poff" - case ExtInterfaceIndex: - return "ld #ifidx" - case ExtNetlinkAttr: - return "ld #nla" - case ExtNetlinkAttrNested: - return "ld #nlan" - case ExtMark: - return "ld #mark" - case ExtQueue: - return "ld #queue" - case ExtLinkLayerType: - return "ld #hatype" - case ExtRXHash: - return "ld #rxhash" - case ExtCPUID: - return "ld #cpu" - case ExtVLANTag: - return "ld #vlan_tci" - case ExtVLANTagPresent: - return "ld #vlan_avail" - case ExtVLANProto: - return "ld #vlan_tpid" - case ExtRand: - return "ld #rand" - default: - return fmt.Sprintf("unknown instruction: %#v", a) - } -} - -// StoreScratch stores register Src into scratch[N]. -type StoreScratch struct { - Src Register - N int // 0-15 -} - -// Assemble implements the Instruction Assemble method. -func (a StoreScratch) Assemble() (RawInstruction, error) { - if a.N < 0 || a.N > 15 { - return RawInstruction{}, fmt.Errorf("invalid scratch slot %d", a.N) - } - var op uint16 - switch a.Src { - case RegA: - op = opClsStoreA - case RegX: - op = opClsStoreX - default: - return RawInstruction{}, fmt.Errorf("invalid source register %v", a.Src) - } - - return RawInstruction{ - Op: op, - K: uint32(a.N), - }, nil -} - -// String returns the instruction in assembler notation. -func (a StoreScratch) String() string { - switch a.Src { - case RegA: - return fmt.Sprintf("st M[%d]", a.N) - case RegX: - return fmt.Sprintf("stx M[%d]", a.N) - default: - return fmt.Sprintf("unknown instruction: %#v", a) - } -} - -// ALUOpConstant executes A = A Val. -type ALUOpConstant struct { - Op ALUOp - Val uint32 -} - -// Assemble implements the Instruction Assemble method. -func (a ALUOpConstant) Assemble() (RawInstruction, error) { - return RawInstruction{ - Op: opClsALU | uint16(opOperandConstant) | uint16(a.Op), - K: a.Val, - }, nil -} - -// String returns the instruction in assembler notation. -func (a ALUOpConstant) String() string { - switch a.Op { - case ALUOpAdd: - return fmt.Sprintf("add #%d", a.Val) - case ALUOpSub: - return fmt.Sprintf("sub #%d", a.Val) - case ALUOpMul: - return fmt.Sprintf("mul #%d", a.Val) - case ALUOpDiv: - return fmt.Sprintf("div #%d", a.Val) - case ALUOpMod: - return fmt.Sprintf("mod #%d", a.Val) - case ALUOpAnd: - return fmt.Sprintf("and #%d", a.Val) - case ALUOpOr: - return fmt.Sprintf("or #%d", a.Val) - case ALUOpXor: - return fmt.Sprintf("xor #%d", a.Val) - case ALUOpShiftLeft: - return fmt.Sprintf("lsh #%d", a.Val) - case ALUOpShiftRight: - return fmt.Sprintf("rsh #%d", a.Val) - default: - return fmt.Sprintf("unknown instruction: %#v", a) - } -} - -// ALUOpX executes A = A X -type ALUOpX struct { - Op ALUOp -} - -// Assemble implements the Instruction Assemble method. -func (a ALUOpX) Assemble() (RawInstruction, error) { - return RawInstruction{ - Op: opClsALU | uint16(opOperandX) | uint16(a.Op), - }, nil -} - -// String returns the instruction in assembler notation. -func (a ALUOpX) String() string { - switch a.Op { - case ALUOpAdd: - return "add x" - case ALUOpSub: - return "sub x" - case ALUOpMul: - return "mul x" - case ALUOpDiv: - return "div x" - case ALUOpMod: - return "mod x" - case ALUOpAnd: - return "and x" - case ALUOpOr: - return "or x" - case ALUOpXor: - return "xor x" - case ALUOpShiftLeft: - return "lsh x" - case ALUOpShiftRight: - return "rsh x" - default: - return fmt.Sprintf("unknown instruction: %#v", a) - } -} - -// NegateA executes A = -A. -type NegateA struct{} - -// Assemble implements the Instruction Assemble method. -func (a NegateA) Assemble() (RawInstruction, error) { - return RawInstruction{ - Op: opClsALU | uint16(aluOpNeg), - }, nil -} - -// String returns the instruction in assembler notation. -func (a NegateA) String() string { - return fmt.Sprintf("neg") -} - -// Jump skips the following Skip instructions in the program. -type Jump struct { - Skip uint32 -} - -// Assemble implements the Instruction Assemble method. -func (a Jump) Assemble() (RawInstruction, error) { - return RawInstruction{ - Op: opClsJump | uint16(opJumpAlways), - K: a.Skip, - }, nil -} - -// String returns the instruction in assembler notation. -func (a Jump) String() string { - return fmt.Sprintf("ja %d", a.Skip) -} - -// JumpIf skips the following Skip instructions in the program if A -// Val is true. -type JumpIf struct { - Cond JumpTest - Val uint32 - SkipTrue uint8 - SkipFalse uint8 -} - -// Assemble implements the Instruction Assemble method. -func (a JumpIf) Assemble() (RawInstruction, error) { - return jumpToRaw(a.Cond, opOperandConstant, a.Val, a.SkipTrue, a.SkipFalse) -} - -// String returns the instruction in assembler notation. -func (a JumpIf) String() string { - return jumpToString(a.Cond, fmt.Sprintf("#%d", a.Val), a.SkipTrue, a.SkipFalse) -} - -// JumpIfX skips the following Skip instructions in the program if A -// X is true. -type JumpIfX struct { - Cond JumpTest - SkipTrue uint8 - SkipFalse uint8 -} - -// Assemble implements the Instruction Assemble method. -func (a JumpIfX) Assemble() (RawInstruction, error) { - return jumpToRaw(a.Cond, opOperandX, 0, a.SkipTrue, a.SkipFalse) -} - -// String returns the instruction in assembler notation. -func (a JumpIfX) String() string { - return jumpToString(a.Cond, "x", a.SkipTrue, a.SkipFalse) -} - -// jumpToRaw assembles a jump instruction into a RawInstruction -func jumpToRaw(test JumpTest, operand opOperand, k uint32, skipTrue, skipFalse uint8) (RawInstruction, error) { - var ( - cond jumpOp - flip bool - ) - switch test { - case JumpEqual: - cond = opJumpEqual - case JumpNotEqual: - cond, flip = opJumpEqual, true - case JumpGreaterThan: - cond = opJumpGT - case JumpLessThan: - cond, flip = opJumpGE, true - case JumpGreaterOrEqual: - cond = opJumpGE - case JumpLessOrEqual: - cond, flip = opJumpGT, true - case JumpBitsSet: - cond = opJumpSet - case JumpBitsNotSet: - cond, flip = opJumpSet, true - default: - return RawInstruction{}, fmt.Errorf("unknown JumpTest %v", test) - } - jt, jf := skipTrue, skipFalse - if flip { - jt, jf = jf, jt - } - return RawInstruction{ - Op: opClsJump | uint16(cond) | uint16(operand), - Jt: jt, - Jf: jf, - K: k, - }, nil -} - -// jumpToString converts a jump instruction to assembler notation -func jumpToString(cond JumpTest, operand string, skipTrue, skipFalse uint8) string { - switch cond { - // K == A - case JumpEqual: - return conditionalJump(operand, skipTrue, skipFalse, "jeq", "jneq") - // K != A - case JumpNotEqual: - return fmt.Sprintf("jneq %s,%d", operand, skipTrue) - // K > A - case JumpGreaterThan: - return conditionalJump(operand, skipTrue, skipFalse, "jgt", "jle") - // K < A - case JumpLessThan: - return fmt.Sprintf("jlt %s,%d", operand, skipTrue) - // K >= A - case JumpGreaterOrEqual: - return conditionalJump(operand, skipTrue, skipFalse, "jge", "jlt") - // K <= A - case JumpLessOrEqual: - return fmt.Sprintf("jle %s,%d", operand, skipTrue) - // K & A != 0 - case JumpBitsSet: - if skipFalse > 0 { - return fmt.Sprintf("jset %s,%d,%d", operand, skipTrue, skipFalse) - } - return fmt.Sprintf("jset %s,%d", operand, skipTrue) - // K & A == 0, there is no assembler instruction for JumpBitNotSet, use JumpBitSet and invert skips - case JumpBitsNotSet: - return jumpToString(JumpBitsSet, operand, skipFalse, skipTrue) - default: - return fmt.Sprintf("unknown JumpTest %#v", cond) - } -} - -func conditionalJump(operand string, skipTrue, skipFalse uint8, positiveJump, negativeJump string) string { - if skipTrue > 0 { - if skipFalse > 0 { - return fmt.Sprintf("%s %s,%d,%d", positiveJump, operand, skipTrue, skipFalse) - } - return fmt.Sprintf("%s %s,%d", positiveJump, operand, skipTrue) - } - return fmt.Sprintf("%s %s,%d", negativeJump, operand, skipFalse) -} - -// RetA exits the BPF program, returning the value of register A. -type RetA struct{} - -// Assemble implements the Instruction Assemble method. -func (a RetA) Assemble() (RawInstruction, error) { - return RawInstruction{ - Op: opClsReturn | opRetSrcA, - }, nil -} - -// String returns the instruction in assembler notation. -func (a RetA) String() string { - return fmt.Sprintf("ret a") -} - -// RetConstant exits the BPF program, returning a constant value. -type RetConstant struct { - Val uint32 -} - -// Assemble implements the Instruction Assemble method. -func (a RetConstant) Assemble() (RawInstruction, error) { - return RawInstruction{ - Op: opClsReturn | opRetSrcConstant, - K: a.Val, - }, nil -} - -// String returns the instruction in assembler notation. -func (a RetConstant) String() string { - return fmt.Sprintf("ret #%d", a.Val) -} - -// TXA copies the value of register X to register A. -type TXA struct{} - -// Assemble implements the Instruction Assemble method. -func (a TXA) Assemble() (RawInstruction, error) { - return RawInstruction{ - Op: opClsMisc | opMiscTXA, - }, nil -} - -// String returns the instruction in assembler notation. -func (a TXA) String() string { - return fmt.Sprintf("txa") -} - -// TAX copies the value of register A to register X. -type TAX struct{} - -// Assemble implements the Instruction Assemble method. -func (a TAX) Assemble() (RawInstruction, error) { - return RawInstruction{ - Op: opClsMisc | opMiscTAX, - }, nil -} - -// String returns the instruction in assembler notation. -func (a TAX) String() string { - return fmt.Sprintf("tax") -} - -func assembleLoad(dst Register, loadSize int, mode uint16, k uint32) (RawInstruction, error) { - var ( - cls uint16 - sz uint16 - ) - switch dst { - case RegA: - cls = opClsLoadA - case RegX: - cls = opClsLoadX - default: - return RawInstruction{}, fmt.Errorf("invalid target register %v", dst) - } - switch loadSize { - case 1: - sz = opLoadWidth1 - case 2: - sz = opLoadWidth2 - case 4: - sz = opLoadWidth4 - default: - return RawInstruction{}, fmt.Errorf("invalid load byte length %d", sz) - } - return RawInstruction{ - Op: cls | sz | mode, - K: k, - }, nil -} diff --git a/vendor/golang.org/x/net/bpf/setter.go b/vendor/golang.org/x/net/bpf/setter.go deleted file mode 100644 index 43e35f0ac24..00000000000 --- a/vendor/golang.org/x/net/bpf/setter.go +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package bpf - -// A Setter is a type which can attach a compiled BPF filter to itself. -type Setter interface { - SetBPF(filter []RawInstruction) error -} diff --git a/vendor/golang.org/x/net/bpf/vm.go b/vendor/golang.org/x/net/bpf/vm.go deleted file mode 100644 index 73f57f1f72e..00000000000 --- a/vendor/golang.org/x/net/bpf/vm.go +++ /dev/null @@ -1,150 +0,0 @@ -// Copyright 2016 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package bpf - -import ( - "errors" - "fmt" -) - -// A VM is an emulated BPF virtual machine. -type VM struct { - filter []Instruction -} - -// NewVM returns a new VM using the input BPF program. -func NewVM(filter []Instruction) (*VM, error) { - if len(filter) == 0 { - return nil, errors.New("one or more Instructions must be specified") - } - - for i, ins := range filter { - check := len(filter) - (i + 1) - switch ins := ins.(type) { - // Check for out-of-bounds jumps in instructions - case Jump: - if check <= int(ins.Skip) { - return nil, fmt.Errorf("cannot jump %d instructions; jumping past program bounds", ins.Skip) - } - case JumpIf: - if check <= int(ins.SkipTrue) { - return nil, fmt.Errorf("cannot jump %d instructions in true case; jumping past program bounds", ins.SkipTrue) - } - if check <= int(ins.SkipFalse) { - return nil, fmt.Errorf("cannot jump %d instructions in false case; jumping past program bounds", ins.SkipFalse) - } - case JumpIfX: - if check <= int(ins.SkipTrue) { - return nil, fmt.Errorf("cannot jump %d instructions in true case; jumping past program bounds", ins.SkipTrue) - } - if check <= int(ins.SkipFalse) { - return nil, fmt.Errorf("cannot jump %d instructions in false case; jumping past program bounds", ins.SkipFalse) - } - // Check for division or modulus by zero - case ALUOpConstant: - if ins.Val != 0 { - break - } - - switch ins.Op { - case ALUOpDiv, ALUOpMod: - return nil, errors.New("cannot divide by zero using ALUOpConstant") - } - // Check for unknown extensions - case LoadExtension: - switch ins.Num { - case ExtLen: - default: - return nil, fmt.Errorf("extension %d not implemented", ins.Num) - } - } - } - - // Make sure last instruction is a return instruction - switch filter[len(filter)-1].(type) { - case RetA, RetConstant: - default: - return nil, errors.New("BPF program must end with RetA or RetConstant") - } - - // Though our VM works using disassembled instructions, we - // attempt to assemble the input filter anyway to ensure it is compatible - // with an operating system VM. - _, err := Assemble(filter) - - return &VM{ - filter: filter, - }, err -} - -// Run runs the VM's BPF program against the input bytes. -// Run returns the number of bytes accepted by the BPF program, and any errors -// which occurred while processing the program. -func (v *VM) Run(in []byte) (int, error) { - var ( - // Registers of the virtual machine - regA uint32 - regX uint32 - regScratch [16]uint32 - - // OK is true if the program should continue processing the next - // instruction, or false if not, causing the loop to break - ok = true - ) - - // TODO(mdlayher): implement: - // - NegateA: - // - would require a change from uint32 registers to int32 - // registers - - // TODO(mdlayher): add interop tests that check signedness of ALU - // operations against kernel implementation, and make sure Go - // implementation matches behavior - - for i := 0; i < len(v.filter) && ok; i++ { - ins := v.filter[i] - - switch ins := ins.(type) { - case ALUOpConstant: - regA = aluOpConstant(ins, regA) - case ALUOpX: - regA, ok = aluOpX(ins, regA, regX) - case Jump: - i += int(ins.Skip) - case JumpIf: - jump := jumpIf(ins, regA) - i += jump - case JumpIfX: - jump := jumpIfX(ins, regA, regX) - i += jump - case LoadAbsolute: - regA, ok = loadAbsolute(ins, in) - case LoadConstant: - regA, regX = loadConstant(ins, regA, regX) - case LoadExtension: - regA = loadExtension(ins, in) - case LoadIndirect: - regA, ok = loadIndirect(ins, in, regX) - case LoadMemShift: - regX, ok = loadMemShift(ins, in) - case LoadScratch: - regA, regX = loadScratch(ins, regScratch, regA, regX) - case RetA: - return int(regA), nil - case RetConstant: - return int(ins.Val), nil - case StoreScratch: - regScratch = storeScratch(ins, regScratch, regA, regX) - case TAX: - regX = regA - case TXA: - regA = regX - default: - return 0, fmt.Errorf("unknown Instruction at index %d: %T", i, ins) - } - } - - return 0, nil -} diff --git a/vendor/golang.org/x/net/bpf/vm_instructions.go b/vendor/golang.org/x/net/bpf/vm_instructions.go deleted file mode 100644 index 0aa307c0611..00000000000 --- a/vendor/golang.org/x/net/bpf/vm_instructions.go +++ /dev/null @@ -1,182 +0,0 @@ -// Copyright 2016 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package bpf - -import ( - "encoding/binary" - "fmt" -) - -func aluOpConstant(ins ALUOpConstant, regA uint32) uint32 { - return aluOpCommon(ins.Op, regA, ins.Val) -} - -func aluOpX(ins ALUOpX, regA uint32, regX uint32) (uint32, bool) { - // Guard against division or modulus by zero by terminating - // the program, as the OS BPF VM does - if regX == 0 { - switch ins.Op { - case ALUOpDiv, ALUOpMod: - return 0, false - } - } - - return aluOpCommon(ins.Op, regA, regX), true -} - -func aluOpCommon(op ALUOp, regA uint32, value uint32) uint32 { - switch op { - case ALUOpAdd: - return regA + value - case ALUOpSub: - return regA - value - case ALUOpMul: - return regA * value - case ALUOpDiv: - // Division by zero not permitted by NewVM and aluOpX checks - return regA / value - case ALUOpOr: - return regA | value - case ALUOpAnd: - return regA & value - case ALUOpShiftLeft: - return regA << value - case ALUOpShiftRight: - return regA >> value - case ALUOpMod: - // Modulus by zero not permitted by NewVM and aluOpX checks - return regA % value - case ALUOpXor: - return regA ^ value - default: - return regA - } -} - -func jumpIf(ins JumpIf, regA uint32) int { - return jumpIfCommon(ins.Cond, ins.SkipTrue, ins.SkipFalse, regA, ins.Val) -} - -func jumpIfX(ins JumpIfX, regA uint32, regX uint32) int { - return jumpIfCommon(ins.Cond, ins.SkipTrue, ins.SkipFalse, regA, regX) -} - -func jumpIfCommon(cond JumpTest, skipTrue, skipFalse uint8, regA uint32, value uint32) int { - var ok bool - - switch cond { - case JumpEqual: - ok = regA == value - case JumpNotEqual: - ok = regA != value - case JumpGreaterThan: - ok = regA > value - case JumpLessThan: - ok = regA < value - case JumpGreaterOrEqual: - ok = regA >= value - case JumpLessOrEqual: - ok = regA <= value - case JumpBitsSet: - ok = (regA & value) != 0 - case JumpBitsNotSet: - ok = (regA & value) == 0 - } - - if ok { - return int(skipTrue) - } - - return int(skipFalse) -} - -func loadAbsolute(ins LoadAbsolute, in []byte) (uint32, bool) { - offset := int(ins.Off) - size := ins.Size - - return loadCommon(in, offset, size) -} - -func loadConstant(ins LoadConstant, regA uint32, regX uint32) (uint32, uint32) { - switch ins.Dst { - case RegA: - regA = ins.Val - case RegX: - regX = ins.Val - } - - return regA, regX -} - -func loadExtension(ins LoadExtension, in []byte) uint32 { - switch ins.Num { - case ExtLen: - return uint32(len(in)) - default: - panic(fmt.Sprintf("unimplemented extension: %d", ins.Num)) - } -} - -func loadIndirect(ins LoadIndirect, in []byte, regX uint32) (uint32, bool) { - offset := int(ins.Off) + int(regX) - size := ins.Size - - return loadCommon(in, offset, size) -} - -func loadMemShift(ins LoadMemShift, in []byte) (uint32, bool) { - offset := int(ins.Off) - - // Size of LoadMemShift is always 1 byte - if !inBounds(len(in), offset, 1) { - return 0, false - } - - // Mask off high 4 bits and multiply low 4 bits by 4 - return uint32(in[offset]&0x0f) * 4, true -} - -func inBounds(inLen int, offset int, size int) bool { - return offset+size <= inLen -} - -func loadCommon(in []byte, offset int, size int) (uint32, bool) { - if !inBounds(len(in), offset, size) { - return 0, false - } - - switch size { - case 1: - return uint32(in[offset]), true - case 2: - return uint32(binary.BigEndian.Uint16(in[offset : offset+size])), true - case 4: - return uint32(binary.BigEndian.Uint32(in[offset : offset+size])), true - default: - panic(fmt.Sprintf("invalid load size: %d", size)) - } -} - -func loadScratch(ins LoadScratch, regScratch [16]uint32, regA uint32, regX uint32) (uint32, uint32) { - switch ins.Dst { - case RegA: - regA = regScratch[ins.N] - case RegX: - regX = regScratch[ins.N] - } - - return regA, regX -} - -func storeScratch(ins StoreScratch, regScratch [16]uint32, regA uint32, regX uint32) [16]uint32 { - switch ins.Src { - case RegA: - regScratch[ins.N] = regA - case RegX: - regScratch[ins.N] = regX - } - - return regScratch -} diff --git a/vendor/modules.txt b/vendor/modules.txt index 699e43c3eb5..0eee805bec5 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -63,10 +63,6 @@ github.com/chai2010/gettext-go github.com/chai2010/gettext-go/mo github.com/chai2010/gettext-go/plural github.com/chai2010/gettext-go/po -# github.com/checkpoint-restore/go-criu/v5 v5.3.0 -## explicit; go 1.13 -github.com/checkpoint-restore/go-criu/v5 -github.com/checkpoint-restore/go-criu/v5/rpc # github.com/cilium/ebpf v0.11.0 ## explicit; go 1.19 github.com/cilium/ebpf @@ -85,9 +81,6 @@ github.com/container-storage-interface/spec/lib/go/csi ## explicit; go 1.17 github.com/containerd/cgroups github.com/containerd/cgroups/stats/v1 -# github.com/containerd/console v1.0.4 -## explicit; go 1.13 -github.com/containerd/console # github.com/containerd/containerd/api v1.7.19 ## explicit; go 1.21 github.com/containerd/containerd/api/services/containers/v1 @@ -245,7 +238,7 @@ github.com/golang/protobuf/ptypes/wrappers # github.com/google/btree v1.0.1 ## explicit; go 1.12 github.com/google/btree -# github.com/google/cadvisor v0.50.0 +# github.com/google/cadvisor v0.51.0 ## explicit; go 1.21 github.com/google/cadvisor/cache/memory github.com/google/cadvisor/client/v2 @@ -489,9 +482,6 @@ github.com/onsi/gomega/types github.com/opencontainers/go-digest # github.com/opencontainers/runc v1.1.15 ## explicit; go 1.18 -github.com/opencontainers/runc/libcontainer -github.com/opencontainers/runc/libcontainer/apparmor -github.com/opencontainers/runc/libcontainer/capabilities github.com/opencontainers/runc/libcontainer/cgroups github.com/opencontainers/runc/libcontainer/cgroups/devices github.com/opencontainers/runc/libcontainer/cgroups/ebpf @@ -502,18 +492,12 @@ github.com/opencontainers/runc/libcontainer/cgroups/fscommon github.com/opencontainers/runc/libcontainer/cgroups/manager github.com/opencontainers/runc/libcontainer/cgroups/systemd github.com/opencontainers/runc/libcontainer/configs -github.com/opencontainers/runc/libcontainer/configs/validate github.com/opencontainers/runc/libcontainer/devices github.com/opencontainers/runc/libcontainer/intelrdt -github.com/opencontainers/runc/libcontainer/keys -github.com/opencontainers/runc/libcontainer/logs -github.com/opencontainers/runc/libcontainer/seccomp -github.com/opencontainers/runc/libcontainer/seccomp/patchbpf github.com/opencontainers/runc/libcontainer/system github.com/opencontainers/runc/libcontainer/user github.com/opencontainers/runc/libcontainer/userns github.com/opencontainers/runc/libcontainer/utils -github.com/opencontainers/runc/types # github.com/opencontainers/runtime-spec v1.2.0 ## explicit github.com/opencontainers/runtime-spec/specs-go @@ -566,7 +550,6 @@ github.com/robfig/cron/v3 github.com/russross/blackfriday/v2 # github.com/seccomp/libseccomp-golang v0.10.0 ## explicit; go 1.14 -github.com/seccomp/libseccomp-golang # github.com/sirupsen/logrus v1.9.3 ## explicit; go 1.13 github.com/sirupsen/logrus @@ -591,9 +574,6 @@ github.com/stretchr/objx github.com/stretchr/testify/assert github.com/stretchr/testify/mock github.com/stretchr/testify/require -# github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 -## explicit -github.com/syndtr/gocapability/capability # github.com/tmc/grpc-websocket-proxy v0.0.0-20220101234140-673ab2c3ae75 ## explicit; go 1.15 github.com/tmc/grpc-websocket-proxy/wsproxy @@ -837,7 +817,6 @@ golang.org/x/mod/module golang.org/x/mod/semver # golang.org/x/net v0.30.0 ## explicit; go 1.18 -golang.org/x/net/bpf golang.org/x/net/context golang.org/x/net/html golang.org/x/net/html/atom