-
Notifications
You must be signed in to change notification settings - Fork 259
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add new gcs hooks, add expected mounts to security policy #1258
Conversation
263fca3
to
b8c51a7
Compare
I checked this out a while ago, but forgot to comment that it looked good and I didnt see anything problematic with the approach. |
a5d40c5
to
8f037da
Compare
Do we have any tests for the expected mounts work in here? |
If you're talking about CRI integration tests, then it's currently blocked on the integrity validation PRs. I am planning on adding the tests once those are merged in as a separate PR. I've done local testing though. |
@katiewasnothere PTAL when you get a chance. |
25f5700
to
309451b
Compare
Introduce a new `wait-paths` binary, which polls file system until requested paths are available or a timeout is reached. Security policy has been updated to have ExpectedMounts entries, which will be used in conjunction with "wait-paths" hook for synchronization purposes. Refactor oci-hook logic into its own internal package and update existing code to use that package. Copy runc HookName and constants definitions to break dependency on runc Introduce ExpectedMounts as part of security policy language and the logic to enforce the policy, which resolves the expected mounts in the UVM and adds a wait-paths hook to the spec. Signed-off-by: Maksim An <maksiman@microsoft.com>
Per pr feedback, only container paths under sandbox mounts are supported as wait-paths. The support for other 2 scenarios can be added as needed. Add positive and negative CRI tests. Signed-off-by: Maksim An <maksiman@microsoft.com>
Signed-off-by: Maksim An <maksiman@microsoft.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm
Prior to this change, GCS allowed only one CreateContainer operation at a time. This isn't an issue in general case, however this doesn't work properly with synchronization via OCI runtime hook. Synchronization via runtime hook was introduced in: microsoft#1258 It injects a CreateRuntime OCI hook, if security policy provides wait paths. This allows container-A to run after container-B, where container-B writes to an empty directory volume shared between the two containers to signal that it's done some setup container-A depends on. In general case, container-A can be started before container-B which results in a deadlock, because CreateContainer request holds a lock to a map, which keeps track of running containers. To resolve the issue, the code has been updated to do a more granular locking when reading/updating the containers map: - Add a new "Status" field to Container object, which can be either "Running" or "Creating". - Remove locking from CreateContainer function - Rework "GetContainer" to "GetRunningContainer", which returns the container object only when it's in "Running" state, otherwise either `gcserr.HrVmcomputeSystemNotFound` or `gcserr.HrVmcomputeInvalidState` error returned. - Add new "AddContainer(id, container)" method, which updates the containers map with new container instances. - Rework CreateContainer to initially add new container objects into the containers map and set the "Status" to "Creating" at the start of the function and set it to "Running" only when the container successfully starts. Changin "GetContainer" to "GetRunningContainer" seemed to be the least invasive change, which allows us to limit code changes in the affected places. If "GetContainer" is left unchanged, then handling of containers in status "Creating" needs to take place and this requires handling cases when (e.g.) a modification request is sent to a container which isn't yet running. Signed-off-by: Maksim An <maksiman@microsoft.com>
Prior to this change, GCS allowed only one CreateContainer operation at a time. This isn't an issue in general case, however this doesn't work properly with synchronization via OCI runtime hook. Synchronization via runtime hook was introduced in: microsoft#1258 It injects a CreateRuntime OCI hook, if security policy provides wait paths. This allows container-A to run after container-B, where container-B writes to an empty directory volume shared between the two containers to signal that it's done some setup container-A depends on. In general case, container-A can be started before container-B which results in a deadlock, because CreateContainer request holds a lock to a map, which keeps track of running containers. To resolve the issue, the code has been updated to do a more granular locking when reading/updating the containers map: - Add a new "Status" field to Container object, which can be either "Running" or "Creating". - Remove locking from CreateContainer function - Rework "GetContainer" to "GetRunningContainer", which returns the container object only when it's in "Running" state, otherwise either `gcserr.HrVmcomputeSystemNotFound` or `gcserr.HrVmcomputeInvalidState` error returned. - Add new "AddContainer(id, container)" function, which updates the containers map with new container instances. - Rework CreateContainer to initially add new container objects into the containers map and set the "Status" to "Creating" at the start of the function and set it to "Running" only when the container successfully starts. Changin "GetContainer" to "GetRunningContainer" seemed to be the least invasive change, which allows us to limit code changes in the affected places. If "GetContainer" is left unchanged, then handling of containers in status "Creating" needs to take place and this requires handling cases when (e.g.) a modification request is sent to a container which isn't yet running. Signed-off-by: Maksim An <maksiman@microsoft.com>
Prior to this change, GCS allowed only one CreateContainer operation at a time. This isn't an issue in general case, however this doesn't work properly with synchronization via OCI runtime hook. Synchronization via runtime hook was introduced in: microsoft#1258 It injects a CreateRuntime OCI hook, if security policy provides wait paths. This allows container-A to run after container-B, where container-B writes to an empty directory volume shared between the two containers to signal that it's done some setup container-A depends on. In general case, container-A can be started before container-B which results in a deadlock, because CreateContainer request holds a lock to a map, which keeps track of running containers. To resolve the issue, the code has been updated to do a more granular locking when reading/updating the containers map: - Add a new "Status" field to Container object, which can be either "Running" or "Creating". - Remove locking from CreateContainer function - Rework "GetContainer" to "GetRunningContainer", which returns the container object only when it's in "Running" state, otherwise either `gcserr.HrVmcomputeSystemNotFound` or `gcserr.HrVmcomputeInvalidState` error returned. - Add new "AddContainer(id, container)" function, which updates the containers map with new container instances. - Rework CreateContainer to initially add new container objects into the containers map and set the "Status" to "Creating" at the start of the function and set it to "Running" only when the container successfully starts. Reworking "GetContainer" to "GetRunningContainer" seemed to be the least invasive change, which allows us to limit updates in the affected places. If "GetContainer" is left unchanged, then handling of containers in status "Creating" needs to take place and this requires handling cases when (e.g.) a modification request is sent to a container which isn't yet running. Signed-off-by: Maksim An <maksiman@microsoft.com>
Prior to this change, GCS allowed only one CreateContainer operation at a time. This isn't an issue in general case, however this doesn't work properly with synchronization via OCI runtime hook. Synchronization via runtime hook was introduced in: microsoft#1258 It injects a CreateRuntime OCI hook, if security policy provides wait paths. This allows container-A to run after container-B, where container-B writes to an empty directory volume shared between the two containers to signal that it's done some setup container-A depends on. In general case, container-A can be started before container-B which results in a deadlock, because CreateContainer request holds a lock to a map, which keeps track of running containers. To resolve the issue, the code has been updated to do a more granular locking when reading/updating the containers map: - Add a new "Status" field to Container object, which can be either "Running" or "Creating". - Remove locking from CreateContainer function - Rework "GetContainer" to "GetRunningContainer", which returns the container object only when it's in "Running" state, otherwise either `gcserr.HrVmcomputeSystemNotFound` or `gcserr.HrVmcomputeInvalidState` error returned. - Add new "AddContainer(id, container)" function, which updates the containers map with new container instances. - Rework CreateContainer to initially add new container objects into the containers map and set the "Status" to "Creating" at the start of the function and set it to "Running" only when the container successfully starts. Reworking "GetContainer" to "GetRunningContainer" seemed to be the least invasive change, which allows us to limit updates in the affected places. If "GetContainer" is left unchanged, then handling of containers in status "Creating" needs to take place and this requires handling cases when (e.g.) a modification request is sent to a container which isn't yet running. Signed-off-by: Maksim An <maksiman@microsoft.com>
Prior to this change, GCS allowed only one CreateContainer operation at a time. This isn't an issue in general case, however this doesn't work properly with synchronization via OCI runtime hook. Synchronization via runtime hook was introduced in: microsoft#1258 It injects a CreateRuntime OCI hook, if security policy provides wait paths. This allows container-A to run after container-B, where container-B writes to an empty directory volume shared between the two containers to signal that it's done some setup container-A depends on. In general case, container-A can be started before container-B which results in a deadlock, because CreateContainer request holds a lock to a map, which keeps track of running containers. To resolve the issue, the code has been updated to do a more granular locking when reading/updating the containers map: - Add a new "Status" field to Container object, which can be either "Running" or "Creating". - Remove locking from CreateContainer function - Rework "GetContainer" to "GetRunningContainer", which returns the container object only when it's in "Running" state, otherwise either `gcserr.HrVmcomputeSystemNotFound` or `gcserr.HrVmcomputeInvalidState` error returned. - Add new "AddContainer(id, container)" function, which updates the containers map with new container instances. - Rework CreateContainer to initially add new container objects into the containers map and set the "Status" to "Creating" at the start of the function and set it to "Running" only when the container successfully starts. Reworking "GetContainer" to "GetRunningContainer" seemed to be the least invasive change, which allows us to limit updates in the affected places. If "GetContainer" is left unchanged, then handling of containers in status "Creating" needs to take place and this requires handling cases when (e.g.) a modification request is sent to a container which isn't yet running. Signed-off-by: Maksim An <maksiman@microsoft.com>
Prior to this change, GCS allowed only one CreateContainer operation at a time. This isn't an issue in general case, however this doesn't work properly with synchronization via OCI runtime hook. Synchronization via runtime hook was introduced in: microsoft#1258 It injects a CreateRuntime OCI hook, if security policy provides wait paths. This allows container-A to run after container-B, where container-B writes to an empty directory volume shared between the two containers to signal that it's done some setup container-A depends on. In general case, container-A can be started before container-B which results in a deadlock, because CreateContainer request holds a lock to a map, which keeps track of running containers. To resolve the issue, the code has been updated to do a more granular locking when reading/updating the containers map: - Add a new "Status" field to Container object, which can be either "Running" or "Creating". - Remove locking from CreateContainer function - Rework "GetContainer" to "GetRunningContainer", which returns the container object only when it's in "Running" state, otherwise either `gcserr.HrVmcomputeSystemNotFound` or `gcserr.HrVmcomputeInvalidState` error returned. - Add new "AddContainer(id, container)" function, which updates the containers map with new container instances. - Rework CreateContainer to initially add new container objects into the containers map and set the "Status" to "Creating" at the start of the function and set it to "Running" only when the container successfully starts. Reworking "GetContainer" to "GetRunningContainer" seemed to be the least invasive change, which allows us to limit updates in the affected places. If "GetContainer" is left unchanged, then handling of containers in status "Creating" needs to take place and this requires handling cases when (e.g.) a modification request is sent to a container which isn't yet running. Signed-off-by: Maksim An <maksiman@microsoft.com>
Prior to this change, GCS allowed only one CreateContainer operation at a time. This isn't an issue in general case, however this doesn't work properly with synchronization via OCI runtime hook. Synchronization via runtime hook was introduced in: microsoft#1258 It injects a CreateRuntime OCI hook, if security policy provides wait paths. This allows container-A to run after container-B, where container-B writes to an empty directory volume shared between the two containers to signal that it's done some setup container-A depends on. In general case, container-A can be started before container-B which results in a deadlock, because CreateContainer request holds a lock to a map, which keeps track of running containers. To resolve the issue, the code has been updated to do a more granular locking when reading/updating the containers map: - Add a new "Status" field to Container object, which can be either "Running" or "Creating". - Remove locking from CreateContainer function - Rework "GetContainer" to "GetRunningContainer", which returns the container object only when it's in "Running" state, otherwise either `gcserr.HrVmcomputeSystemNotFound` or `gcserr.HrVmcomputeInvalidState` error returned. - Add new "AddContainer(id, container)" function, which updates the containers map with new container instances. - Rework CreateContainer to initially add new container objects into the containers map and set the "Status" to "Creating" at the start of the function and set it to "Running" only when the container successfully starts. Reworking "GetContainer" to "GetRunningContainer" seemed to be the least invasive change, which allows us to limit updates in the affected places. If "GetContainer" is left unchanged, then handling of containers in status "Creating" needs to take place and this requires handling cases when (e.g.) a modification request is sent to a container which isn't yet running. Signed-off-by: Maksim An <maksiman@microsoft.com>
Prior to this change, GCS allowed only one CreateContainer operation at a time. This isn't an issue in general case, however this doesn't work properly with synchronization via OCI runtime hook. Synchronization via runtime hook was introduced in: #1258 It injects a `CreateRuntime` OCI hook, if security policy provides wait paths. This allows container-A to run after container-B, where container-B writes to an empty directory volume shared between the two containers to signal that it's done some setup container-A depends on. In general case, container-A can be started before container-B which results in a deadlock, because `CreateContainer` request holds a lock to a map, which keeps track of running containers. To resolve the issue, the code has been updated to do a more granular locking when reading/updating the containers map: - Add a new "status" field to Container object and atomic setter/getter, which can be either "Created" or "Creating". New `uint32` type alias and constants were added to represent the values (`containerCreated` and `containerCreating`) - Remove locking from `CreateContainer` function - Rework `GetContainer` to `GetCreatedContainer`, which returns the container object only when it's in `containerCreated` state, otherwise either `gcserr.HrVmcomputeSystemNotFound` or `gcserr.HrVmcomputeInvalidState` error returned. - Add new `AddContainer(id, container)` function, which updates the containers map with new container instances. - Rework `CreateContainer` to initially add new container objects into the containers map and set the "status" to `containerCreating` at the start of the function and set it to `containerCreated` only when the container is successfully created in runtime. Reworking `GetContainer` to `GetCreatedContainer` seemed to be the least invasive change, which allows us to limit updates in the affected places. If `GetContainer` is left unchanged, then handling of containers in status "Creating" needs to take place and this requires handling cases when (e.g.) a modification request is sent to a container which isn't yet running. Additionally update synchronization CRI tests to use go routines to properly reproduce the scenario. Signed-off-by: Maksim An <maksiman@microsoft.com>
Follow up PR to add tests for wait-paths after initial PR microsoft#1258 was merged. Signed-off-by: Maksim An <maksiman@microsoft.com>
Follow up PR to add tests for wait-paths after initial PR #1258 was merged. Signed-off-by: Maksim An <maksiman@microsoft.com>
…1258) Introduce a new `wait-paths` binary, which polls file system until requested paths are available or a timeout is reached. Security policy has been updated to have `ExpectedMounts` entries, which will be used in conjunction with "wait-paths" hook for synchronization purposes. Refactor oci-hook logic into its own internal package and update existing code to use that package. Copy runc HookName and constants definitions to break dependency on runc Introduce `ExpectedMounts` as part of security policy language and the logic to enforce the policy, which resolves the expected mounts in the UVM and adds a wait-paths hook to the spec. Add positive and negative CRI tests. Signed-off-by: Maksim An <maksiman@microsoft.com>
…t#1355) Prior to this change, GCS allowed only one CreateContainer operation at a time. This isn't an issue in general case, however this doesn't work properly with synchronization via OCI runtime hook. Synchronization via runtime hook was introduced in: microsoft#1258 It injects a `CreateRuntime` OCI hook, if security policy provides wait paths. This allows container-A to run after container-B, where container-B writes to an empty directory volume shared between the two containers to signal that it's done some setup container-A depends on. In general case, container-A can be started before container-B which results in a deadlock, because `CreateContainer` request holds a lock to a map, which keeps track of running containers. To resolve the issue, the code has been updated to do a more granular locking when reading/updating the containers map: - Add a new "status" field to Container object and atomic setter/getter, which can be either "Created" or "Creating". New `uint32` type alias and constants were added to represent the values (`containerCreated` and `containerCreating`) - Remove locking from `CreateContainer` function - Rework `GetContainer` to `GetCreatedContainer`, which returns the container object only when it's in `containerCreated` state, otherwise either `gcserr.HrVmcomputeSystemNotFound` or `gcserr.HrVmcomputeInvalidState` error returned. - Add new `AddContainer(id, container)` function, which updates the containers map with new container instances. - Rework `CreateContainer` to initially add new container objects into the containers map and set the "status" to `containerCreating` at the start of the function and set it to `containerCreated` only when the container is successfully created in runtime. Reworking `GetContainer` to `GetCreatedContainer` seemed to be the least invasive change, which allows us to limit updates in the affected places. If `GetContainer` is left unchanged, then handling of containers in status "Creating" needs to take place and this requires handling cases when (e.g.) a modification request is sent to a container which isn't yet running. Additionally update synchronization CRI tests to use go routines to properly reproduce the scenario. Signed-off-by: Maksim An <maksiman@microsoft.com>
Introduce a new
wait-paths
binary, which polls file systemuntil requested paths are available or a timeout is reached.
Security policy has been updated to have ExpectedMounts entries,
which will be used in conjunction with "wait-paths" hook for
synchronization purposes.
Refactor oci-hook logic into its own internal package and update
existing code to use that package. Copy runc HookName and constants
definitions to break dependency on runc
Introduce ExpectedMounts as part of security policy language and
the logic to enforce the policy, which resolves the expected mounts
in the UVM and adds a wait-paths hook to the spec.
Signed-off-by: Maksim An maksiman@microsoft.com