umoci

repository·main·Indexed 21 days ago

https://github.com/opencontainers/umoci

A reference implementation of the OCI image specification used to create, manipulate, and interact with container images. It provides a CLI for unpacking images into runtime bundles, modifying filesystems, repacking them into new images, and managing OCI image layouts. It includes Go packages for converting image configurations to runtime configurations, generating modifications to configuration blobs, and handling OCI layers using mtree specifications.

Tokens
21.3K
Snippets
78
Records
105
Agent score
75%

What's inside umoci

  1. Overview of the umoci/oci package

    main
    The umoci/oci package is a reimplementation of several features from upstream OCI projects. It also implements features that are intended to be maintained upstream, such as generate. The primary design goal of this package is to be completely upstreamable.
  2. Overview of umoci

    main
    umoci is a tool designed for high-level modification of OCI (Open Container Initiative) image layouts and their tagged images. It abstracts the complexities of the OCI image specification, allowing users to perform arbitrary modifications where umoci manages the underlying blobs during high-level operations (such as repacking).
  3. Use umoci raw for advanced image tooling

    main
    The umoci raw subcommand provides access to advanced internal image tooling. These commands are intended for users who are deeply familiar with the OCI (Open Container Initiative) image specification. For most standard use cases, the top-level tools like umoci unpack are sufficient and recommended instead of the raw subcommands to avoid unintended implications.
  4. Understanding the `umoci/oci/layer` implementation

    main

    The umoci/oci/layer package provides a custom implementation of OCI layer creation and runtime bundle generation.

    Key characteristics include:

    • Mtree Support: Unlike the standard oci-create-layer functions, this implementation uses mtree specifications, allowing for different metadata handling.
    • Runtime Bundle Generation: It implements oci-create-runtime-bundle functionality, but uses a Content Addressable Storage (CAS) based API to provide more granular control during the bundle generation process.
    • Whiteout Handling: It functions as a whiteout tar archive generator. Note that the whiteout format is subject to change based on evolving OCI image specifications.
  5. How image mutation and blob replacement works

    main

    Because OCI images are based on a content-addressable blob store, blobs cannot be modified in place. Instead, umoci performs mutations by creating new versions of blobs and updating the reference chain.

    The mutation lifecycle:

    1. New Blob Creation: umoci creates a new version of the blob being replaced.
    2. Reference Walking: umoci walks up the referencing path from the replaced blob toward the root.
    3. Bubbling Up: Every blob in the ancestor path that references the old blob is replaced with a new blob referencing the new version. This process continues until it reaches the root index.json.
    4. Index Update: umoci creates or replaces a top-level index.json entry to point to the newly created tree.

    Key Benefit: De-duplication Umoci only replaces blobs in the direct ancestor path of the modification. Any blobs not in that path remain unchanged and are automatically de-duplicated, ensuring that unchanged data is not unnecessarily copied.

  6. Mitigating Path Traversal Vulnerabilities in umoci

    main

    umoci protects against path traversal attacks (where an image attempts to access files outside its intended root directory) using several layers of defense:

    1. Secure Path Computation: All destination and source path computations use the filepath-securejoin library. This library performs manual symlink and lexical evaluation within a specific scope to prevent escaping the intended directory.
    2. Sanity Checks: umoci performs additional defensive checks to ensure filesystem modifications based on image input do not affect anything outside the intended directory root.
    3. Inode Protection: To prevent attacks involving hardlinks to files outside the root filesystem, umoci avoids mutating existing inodes and instead always replaces them.

    Security Warning: Users should be aware of the risks when interacting with a foreign filesystem rootfs. It is recommended to use a virtualization system (such as chroot or containers) when interacting with the rootfs expanded by umoci rather than interacting with it directly on the host filesystem.

  7. How rootless emulation works in umoci

    main

    umoci provides first-class support for rootless containers, specifically focusing on unpacking, repacking, and generating runtime configurations compatible with runc for starting rootless containers.

    Because unprivileged users are restricted by the operating system from creating certain device inodes and set-uid binaries, the root filesystem created by umoci in rootless mode will likely not match a filesystem created by a privileged user. To mitigate this, umoci:

    1. Emulates correct behavior as closely as possible during unpacking.
    2. Generates runtime configurations designed to help runc emulate the correct behavior.
    3. Supports the user.rootlesscontainers specification, which enables further emulation of operations like chown(2) inside the container when used with tools like PRoot.
  8. Convert image configuration to runtime configuration using `umoci/oci/config/convert`

    main

    The umoci/oci/config/convert package provides an implementation for converting an OCI image configuration into a runtime configuration (bundle configuration). This process is necessary because image configurations are platform-agnostic, whereas runtime bundles require platform-specific details.

    This implementation is unopinionated and designed to allow consumers to inject their own extensions during the runtime configuration generation process.

  9. Preventing Arbitrary Inode and Mode Creation

    main

    When running as a privileged user (e.g., having CAP_SYS_ADMIN on Linux), umoci is potentially vulnerable to attacks where OCI image layers (tar archives) contain inode information designed to create dangerous files, such as block devices with arbitrary major/minor numbers or unsafe set-uid binaries.

    Defense Mechanism: To mitigate this, umoci sets the bundle directory permissions to chmod go-rwx. This prevents unprivileged users from resolving dangerous inodes or setuid binaries created during the process.

    Note on Rootless Mode: If umoci is running in rootless mode, it is not susceptible to this specific attack because it relies on standard VFS operations and the operating system's existing access control restrictions.

  10. How umoci generates delta layers using manifests

    main

    umoci generates delta layers without requiring filesystem snapshots, overlays, or full copies of the original root filesystem. It achieves this by using mtree(8) manifests.

    The process works as follows:

    1. Initial Manifest: After the root filesystem is extracted, a full manifest is generated from it.
    2. New Manifest: When a modification is requested, a new manifest is generated for the modified state.
    3. Comparison: umoci compares the two manifests. Any inconsistencies found between the original and the new manifest are then packaged into a delta layer.

    This approach allows umoci to function on any modern Unix-like operating system by relying on simple manifest comparisons rather than complex filesystem features.

  11. How image creation works in umoci

    main

    Creating an image in umoci follows a two-step conceptual model:

    1. Initialize the Layout: Use umoci init to create the filesystem structure (the "husk") required for an OCI image layout. At this stage, the layout is empty and contains only a dummy configuration.
    2. Define the Image: Use umoci new to instantiate a specific image (with a name and tag) within that layout.

    Once created, these images can be operated on using the standard umoci workflow as if they were normal, existing images.

  12. Use umoci/oci/config/generate to modify OCI image configurations

    main

    The umoci/oci/config/generate package is a library designed to facilitate generating modifications to an OCI image configuration blob. It targets configuration blobs of type application/vnd.oci.image.config.v1+json as defined by the OCI Image Specification.

    Developers can use this library to programmatically implement changes to an image's configuration rather than manually manipulating JSON blobs.