Skip to content

fix(deps): update rust crate gix to 0.90 [security] - #1347

Merged
ferrlabs-renovate[bot] merged 4 commits into
mainfrom
renovate/crate-gix-vulnerability
Oct 24, 2026
Merged

ferrlabs-renovate[bot] merged 4 commits into
mainfrom
renovate/crate-gix-vulnerability

Conversation

@ferrlabs-renovate

Copy link
Copy Markdown
Contributor

This PR contains the following updates:

Package Type Update Change
gix dependencies minor 0.89 → 0.90

gitoxide gix: untrusted .git/config disables filesystem .git-protection path checks via unfiltered protect_options()

GHSA-q54r-jf2p-rfr2

More information

Details

Summary

In the gix crate, Cache::protect_options() in gix/src/config/cache/access.rs reads the three filesystem path-protection settings (core.protectHFS, core.protectNTFS, and gitoxide.core.protectWindows) with the unfiltered gix_config::File::boolean() accessor instead of the trust-aware boolean_filter() accessor used by every other security-critical config read in the same file. When a repository is opened with reduced trust (an ownership mismatch, which maps .git/config sections to Trust::Reduced), these protection settings should not be honored from the untrusted repository-local config. Because the trust filter is skipped, an attacker who controls a repository's .git/config on a shared filesystem can set core.protectNTFS = false and/or core.protectHFS = false, disabling the .git path-confusion checks that run during checkout, index creation, merge, and tree editing. On case-insensitive filesystems this lets crafted tree entries resolve to the .git directory and overwrite hooks or config.

Root Cause

Repositories opened under Trust::Reduced install a section filter (is_trusted) so that security-relevant settings coming from an untrusted repository-local .git/config are ignored. The Cache struct stores this filter and applies it throughout gix/src/config/cache/access.rs for diff drivers, merge drivers, URL rewrites, scheme permissions, lock timeout, and checkout workers. protect_options() is the exception: it reads the path-protection booleans through self.resolved.boolean(...), which delegates to boolean_filter(key, |_| true) and therefore accepts values from every section regardless of trust. As a result, an untrusted repository-local setting of core.protectHFS/core.protectNTFS/gitoxide.core.protectWindows overrides the safe defaults, defeating the trust boundary for exactly the controls that are meant to prevent .git path-confusion attacks.

gix/src/config/cache/access.rs:300  Cache::protect_options() : vulnerable function
gix/src/config/cache/access.rs:306  self.resolved.boolean(gitoxide.core.protectWindows)  (unfiltered)
gix/src/config/cache/access.rs:310  self.resolved.boolean(core.protectHFS)              (unfiltered)
gix/src/config/cache/access.rs:314  self.resolved.boolean(core.protectNTFS)             (unfiltered)
gix-config/src/file/access/comfort.rs:89  boolean() delegates to boolean_filter(key, |_| true)
gix/src/config/mod.rs:61  is_trusted() : the filter that would reject untrusted repo-local sections
gix-validate/src/path.rs:98  component() : path validation that honors the resulting options
Impact

An attacker who owns a repository on a filesystem shared with the victim (a multi-user development host, a shared or network-mounted checkout, or a CI workspace reused across jobs) edits that repository's .git/config to disable one or both of core.protectHFS and core.protectNTFS. When the victim opens the repository with a gix-based tool, the ownership mismatch yields Trust::Reduced, which should neutralize these untrusted settings, but protect_options() honors them anyway. The attacker also commits tree entries whose names are filesystem-specific encodings of .git (for example NTFS short names such as GIT~1, NTFS alternate-data-stream or trailing-dot/space variants, or HFS+ forms using ignorable code points). When the victim performs a checkout, index build, merge, or tree edit, path validation no longer rejects these names, so on a case-insensitive filesystem (Windows NTFS, macOS HFS+) they collapse to the real .git directory. This permits overwriting repository hooks and configuration, which plausibly leads to arbitrary command execution in the victim's context on the next Git operation that runs a hook. The confidentiality, integrity, and availability impact follows from control over the victim's .git directory and any resulting hook execution; hook execution was not freshly executed here and is characterized as the plausible consequence of the demonstrated path-protection bypass.

Proof of Concept

The following unit test places the config cache in the exact state produced after a submodule or repository is initialized (only url copied to the local config) and shows that the attacker's path-protection override from the repository-local config is honored even though it should be filtered under reduced trust. The same boolean() vs boolean_filter() discrepancy is directly observable in source.

// Demonstrates that core.protectNTFS from an untrusted repository-local
// section is honored by the unfiltered read in protect_options().
use std::str::FromStr;

// Trusted (system/global) config: protection on by default.
// Untrusted repository-local config (.git/config) disables NTFS protection.
let repo_local = gix_config::File::from_str("[core]\n    protectNTFS = false").unwrap();

// Reading core.protectNTFS with the trust-aware filter would reject the
// repository-local section; reading it unfiltered (as protect_options does)
// returns Some(false), disabling the .git-confusion check.
let filtered = repo_local.boolean_filter("core.protectNTFS", |_| false); // trusted-only
let unfiltered = repo_local.boolean("core.protectNTFS");                  // what protect_options uses
eprintln!("filtered (trusted only) = {:?}", filtered);   // None  -> safe default kept
eprintln!("unfiltered (vulnerable) = {:?}", unfiltered); // Some(Ok(false)) -> protection disabled
filtered (trusted only) = None
unfiltered (vulnerable) = Some(Ok(false))

Source confirmation that boolean() performs no trust filtering:

// gix-config/src/file/access/comfort.rs:89
pub fn boolean(&self, key: impl AsKey) -> Result<Option<bool>> {
    self.boolean_filter(key, |_| true)
}
Attack Chain
  1. Exposure: The attacker owns a repository on a filesystem shared with the victim; the victim opens it with a gix-based tool, and the ownership mismatch sets the repository's config sections to Trust::Reduced (gix/src/open/options.rs:215 installs the is_trusted section filter).
  2. Control: The attacker writes core.protectNTFS = false (and/or core.protectHFS = false) into the repository-local .git/config, plus tree entries whose names are filesystem-specific encodings of .git.
  3. Path: During checkout, index build, merge, or tree edit, each call site invokes protect_options() (gix/src/clone/checkout.rs:103, gix/src/repository/index.rs:206, gix/src/repository/merge.rs:153 and :214, gix/src/object/tree/editor.rs:24, gix/src/config/cache/access.rs:362).
  4. Guard: The is_trusted filter (gix/src/config/mod.rs:61) would reject the untrusted repository-local section, but protect_options() reads via self.resolved.boolean(...) (gix/src/config/cache/access.rs:306,310,314), which delegates to boolean_filter(key, |_| true) and ignores the filter.
  5. Primitive: gix_validate::path::component() (gix-validate/src/path.rs:98) receives protect_hfs=false and/or protect_ntfs=false, so the HFS+/NTFS .git-confusion checks are skipped. When only one protection is disabled, the combined-case fallback at gix-validate/src/path.rs:137 does not run, and the remaining single-filesystem check does not cover the other filesystem's encodings.
  6. Result: Crafted tree entries that encode .git pass validation and are written to disk; on a case-insensitive filesystem they resolve into the real .git directory, overwriting hooks and configuration and plausibly yielding code execution in the victim's context.
Bypass Evidence

The protection under test is the reduced-trust section filter that is supposed to stop untrusted repository-local config from altering security settings. The strongest counter-argument is the case-insensitive .git fallback in gix-validate/src/path.rs:137, which rejects a plain .git match when both HFS+ and NTFS protections are off. That fallback is insufficient for two reasons verified in source: it only runs when BOTH protect_hfs and protect_ntfs are false (!(protect_hfs | protect_ntfs) at line 137), so disabling a single protection leaves it inactive; and even when it runs, its exact eq_ignore_ascii_case(b".git") test does not cover filesystem-specific encodings such as NTFS short names (GIT~1), NTFS trailing-dot/space or alternate-data-stream forms, or HFS+ ignorable-code-point variants, which are precisely what the dedicated is_dot_hfs/is_dot_git_ntfs checks (now skipped) exist to catch. The boolean() accessor was confirmed to apply no trust filtering (gix-config/src/file/access/comfort.rs:89), and the sibling reads in the same file consistently apply filter_config_section, so the unfiltered read is a genuine deviation rather than an intentional exemption. This issue is distinct from the previously disclosed submodule command-execution bypass (CVE-2026-40034 / GHSA-f26g-jm89-4g65): that advisory's fix changed only the gix-submodule crate and gix/src/repository/submodule.rs and never touched protect_options(), so this code path and its remediation boundary are not covered by it.

Affected Versions
  • Ecosystem: rust
  • Package: gix (crates.io)
  • Confirmed affected range: >= 0.88.0, <= 0.89.0
  • Latest release checked: 0.89.0 (crates.io)
  • Fix status: 0.90.0

protect_options() was introduced in gix 0.88.0 and did not exist in earlier releases; before then the path-validation options were not configurable from repository config in this way. The unfiltered read is present from introduction through the latest published release (0.89.0).

Suggested Fix

Read the path-protection settings through the same trust-aware accessor used by the other security-critical reads in gix/src/config/cache/access.rs: replace each self.resolved.boolean(...) call in protect_options() with self.resolved.boolean_filter(..., &mut self.filter_config_section.clone()) so that untrusted repository-local sections are excluded under Trust::Reduced and the safe defaults are retained. The fix must apply to all three keys (core.protectHFS, core.protectNTFS, gitoxide.core.protectWindows) so that no single protection can be disabled from untrusted config. As an interim mitigation, operators can avoid opening untrusted or other-user-owned repositories with gix-based tools on shared or case-insensitive filesystems; this does not remove the underlying bypass.


Reported by zx.

Severity

  • CVSS Score: 7.3 / 10 (High)
  • Vector String: CVSS:3.1/AV:L/AC:L/PR:L/UI:R/S:U/C:H/I:H/A:H

References

This data is provided by OSV and the GitHub Advisory Database (CC-BY 4.0).


Release Notes

GitoxideLabs/gitoxide (gix)

v0.90.0: gix v0.90.0

Compare Source

New Features (BREAKING)
  • add worktree locking and a lock override that preserves changes

    Expose Worktree::set_lock(Option<&BStr>) and worktree::Proxy::set_lock()
    so callers can protect linked worktrees from pruning, moving, or removal,
    including when their checkout is offline. Implement file handling in
    gix_worktree::set_lock(): preserve byte-oriented reasons, append Git's
    trailing newline when needed, and make unlocking idempotent. Reject the
    main worktree in the porcelain and avoid writing through lock-file symlinks.

    Previously Force::OverrideLock also discarded local changes and initialized
    submodules. Add Force::OverrideLockKeepChanges to bypass just the lock check,
    retaining status and submodule validation. This expands an exhaustive public
    enum, so adapt the Tix caller in the same commit; existing CLI force levels
    retain their behavior.

    Git reference: v2.56.0-116-g6de20f6092
    (6de20f6092dcf9bdb1c8efe03db4b70c82b423dd), builtin/worktree.c
    lock/unlock/removal, wrapper.c newline encoding, and
    t/t2403-worktree-move.sh. Git's worktree remove -ff bypasses both lock and
    cleanliness checks; the new mode deliberately permits bypassing only the lock.
    exposes a pre-existing unresolved with_fetch_options link in clone docs.

Test
  • worktree removal with late writes to both roots Inject bounded writes through removal progress after scanning, proving that
    one-pass deletion leaves files while default retries finish.
Performance
  • don't look for new packs before writing an object
Reverted (BREAKING)
  • remove the obsolete max-performance-safe feature gix always uses zlib-rs, so the safe bundle no longer differs from
    max-performance. Make max-performance own the default cache setup and
    update defaults, cache tests, and developer commands. Downstream users of
    the removed name must select max-performance instead.
New Features
  • add Submodule::resolved_url() for cloning
    Definitely went through the tests quickly, besides the usual
    'make it a shell script', but poked the URL resolution and Windows
    special cases.
    Some of the newly added drive-prefix tests are truly from another world,
    and I don't think I could ever have written those, for better or worse.

    Relative submodule URLs in .gitmodules refer to the superproject's
    upstream, even when that upstream uses ssh://, git://, or SCP syntax.
    Passing the existing Submodule::url() result directly to a clone treats
    ./ and ../ entries as local paths instead.

    Document url() as the raw configured accessor and add resolved_url()
    for cloning or fetching. Port Git's byte-oriented relative_url() rules
    from remote.c, select the current branch's remote or the default remote,
    and fall back to the superproject itself when the selected URL is missing.
    Make local paths absolute so the result does not depend on the caller's
    working directory. Honor configuration overrides as initialized URLs,
    avoiding a second remote-relative resolution of local URLs written by
    git submodule init.

    Validate transport and local URLs, traversal errors, default-remote
    selection, initialized overrides, unborn and bare repositories, and
    non-UTF-8 local paths in disposable repositories. Compare resolution with
    git submodule init; include native-separator coverage for Windows.

  • expose selected global attribute paths

    Allow callers that retain detached diff results to track the attribute files
    selected by the repository. Reuse the existing resolver so permissions,
    configuration interpolation, fallback paths, and precedence stay consistent
    with the attribute stack.

    Return selected paths even when files are missing so their later creation can
    invalidate cached results. Per-directory attributes and info/attributes
    remain separate because their locations are already known to the caller.

  • provide safe interrupt setup and handle SIGHUP

    Applications that only need the shared cancellation flag should not have to
    supply an unsafe signal callback. Add interrupt::init_handler_default() as a
    safe entry point while preserving the callback and grace policy of an existing
    registration, including when a UI runs inside the gix command.

    Treat Unix SIGHUP like the other termination signals so long-running work can
    observe cancellation and callers can restore terminal state before exiting.
    It previously bypassed the shared flag and terminated immediately. Repeated
    signals retain the existing forced-termination policy.

    Exercise all supported termination signals and nested safe registration in
    isolated subprocesses. Four interrupt tests pass with the feature enabled and
    two pass without it.

  • add Remote::default_branch() to learn the default branch of a remote without connecting to it.
    git clone and git remote set-head record the default branch of a remote in the symbolic reference
    refs/remotes/<name>/HEAD, which points to the remote-tracking branch of that branch, like
    refs/remotes/origin/main. Since Git 2.48, git fetch also creates it if it's missing.

  • make repository paths absolute without reloading

    Went through the tests quite quickly, thinking their are deep and thorough
    as usual.

    Relative repository paths depend on the process current directory. Changing it
    after opening a repository can redirect checkout validation, Git-link handling,
    HEAD and object reads, or index persistence away from the intended repository.

    Add Repository::make_paths_absolute() to anchor the selected Git directory,
    common directory, worktree, index, and object database to the CWD captured at
    opening. Unlike reload(), this keeps runtime configuration, reference namespaces,
    and in-memory objects. Join paths lexically so missing worktrees remain supported
    and destination symlinks are still rejected. Leave existing clones unchanged,
    avoid partial updates on failure, and make repeated calls a no-op.

    Recreate relative reference and object stores through their existing APIs.
    Reset caches carrying relative index paths or store-specific pack IDs while
    preserving outstanding snapshots.

    Use an anchored repository view for initial checkout, and anchor global attribute
    paths before optional-file metadata checks. Document the interpolation helper
    and its captured-directory behavior.

    Cover CWD changes, main and linked worktrees, bare repositories, missing checkouts,
    index overrides, retained runtime state, idempotence, and failed reconstruction.
    Include a Windows-only test for rejecting unresolved drive-relative index paths
    without partially updating the repository.

  • separate linked worktree registration from checkout

    Skipped over the tests, knowing they are very detailed
    can be trusted by now.

    Add Repository::prepare_add_worktree() with consuming checkout and explicit
    persistence. Persisted repositories can run their initial checkout later, even
    after their checkout directory is removed, while failed unpersisted checkouts
    roll back their owned data.

Bug Fixes
  • create SHA-256 repositories for object_hash: None in SHA-256-only builds
    Previously a SHA-1 repository was created that the same build couldn't open.
    Now None falls back to the build's default object format.

  • respect section trust for filesystem path protections

    GHSA-q54r-jf2p-rfr2 reports that path-protection configuration did not
    respect the section filter used for security-relevant settings. Use the
    filter for core.protectHFS, core.protectNTFS, and
    gitoxide.core.protectWindows, including the latter's early read for the
    reference store. Keep platform defaults and boolean error handling intact.

    Read-only fixtures exercise local and worktree configuration, full and
    reduced trust, custom filters, trusted API overrides, and malformed
    values in strict and lenient mode. Before the fix, reduced-trust settings
    replaced the defaults and a rejected malformed Windows setting prevented
    opening. Validation also exercises representative path names.

    Git baseline: the local Git reference identifies itself as v2.56.GIT.
    Its t/t1014-read-tree-confusing.sh and read-cache.c:verify_path_internal
    cover filesystem-specific path protections. Git's ownership policy in
    setup.c:ensure_valid_ownership rejects dubious ownership, whereas gix
    supports reduced trust by filtering configuration.

  • match Git clone reference handling and preserve offline defaults

    The prior CI run failed check-mode because make_clone_refs.sh had a
    shebang without its executable bit. Its ARM32 tests also ran Git 2.47.3,
    which rejects clone --revision; the matrix mistook that unsupported
    option for a clone failure and disagreed with successful gix clones.

    Mark the fixture executable and detect revision support from git clone -h.
    Skip only revision baselines on older Git, retaining all 72 other cases
    and the independent gix revision tests. Modern Git still exercises all
    81 baseline cases. Capture help despite its expected nonzero exit status.

  • match Git clone reference handling and preserve offline defaults

    gix clones recorded remote HEAD as a direct object ID, losing the
    branch relationship needed by later fetches and Remote::default_branch().
    Bare clones also used the ordinary remote-tracking layout, while detached
    remote heads and custom destinations selected different references from
    git clone.

    Match Git's clone orchestration and reference selection:

    • Store bare-clone branches in refs/heads/*, without a default persisted
      fetch refspec, tracking HEAD, or branch upstream configuration. Keep
      explicit refspecs persistent and use WithWorktree plus fetch_only()
      for ordinary clones without a checkout.
    • Select the advertised symbolic target or guess a branch matching a
      detached HEAD, preferring init.defaultBranch, then master, then the
      first matching branch by name. Record the selected branch's first mapped
      peer before updating local HEAD, including overwriting a branch named
      HEAD; omit tracking HEAD when the selected target is excluded.
    • Detach and peel tag and revision selections, check out the selected
      HEAD, and align shallow selection, tag policy, initial packed-reference
      reflogs, and persisted revision configuration with Git. Preserve the
      reference directory required for repository discovery.

    Preserve fetch-source identity when deriving an offline default branch.
    Recognize refs/heads/ sources and exact heads/<name> sources, including
    an exact source whose mapping was deduplicated against a glob. Return
    None for sources whose branch cannot be identified offline, count all
    ambiguous mappings, and share reverse mapping with upstream-branch lookup.

    Consult Git's builtin/clone.c and remote.c, and add deterministic
    Git-produced baselines for 27 cases in normal, no-checkout, and bare modes.
    Compare complete references, relevant configuration, reflog IDs, checkout
    contents, shallow boundaries, and success or failure with installed Git.
    Keep source fixtures read-only and read their existing refs through gix.
    Update API docs, CLI help and update printing, and affected clone/fetch tests.

    Known difference: replacing a direct branch named HEAD with the tracking
    symref logs a null old object ID in gix-ref; Git logs the resolved target.
    The baseline test explicitly checks this exception. Replacement-only custom
    refspecs remain a gix extension rather than being compared with Git's
    supplementary clone mappings.

  • resolve linked worktree submodules in their private Git directory

    Git stores each linked superproject's submodule repositories under
    .git/worktrees/<id>/modules/<name>, separately from the main worktree's
    .git/modules/<name> repositories. Using common_dir() for
    Submodule::git_dir() could open the main worktree's submodule before
    initialization or after deinitialization of the linked submodule.

    Derive the path from the superproject's git_dir() instead. Preserve name
    validation and the precedence of an existing submodule .git file.

    Cover initial checkout, initialization, and deinitialization using Git to
    populate a disposable linked worktree created by gix. Check that the main
    submodule remains populated and that linked repository state and opening
    follow its own lifecycle.

  • honor replacement refs and bypass stale commit graphs

    Enable standard replacement refs by default and honor core.useReplaceRefs
    with the same polarity as Git. The presence of GIT_NO_REPLACE_OBJECTS
    disables them regardless of its value.

    Commit graphs contain original parent links, so skip them while object
    replacements are active, including when a caller forces or supplies a
    cache. Per-handle raw reads can still use the graph. Document the corrected
    opening and graph behavior.

    The regression first failed on the original code, then passed for ordinary
    open/discovery in bare and non-bare repositories, reopening after a graft,
    configuration and environment disablement, explicit raw reads, supplied
    and forced graphs, merge-base, and graph removal. All 503 gix integration
    tests passed; the regression also passed with only revision,sha1 enabled.
    Native rebuilt gix log and tix show match Git across two grafts in both
    repository kinds with pre-existing raw graphs.

Commit Statistics
  • 36 commits contributed to the release over the course of 14 calendar days.
  • 14 days passed between releases.
  • 16 commits were understood as conventional.
  • 0 issues like '(#ID)' were seen in commit messages
Commit Details
view details
  • Uncategorized
    • Merge pull request #​3082 from 10ne1/sha256-ci-fixes (b8ef9ea)
    • Review (6260a55)
    • Remove hard-coded SHA-1 from the Commit::short_id() doctest (75ca154)
    • Create SHA-256 repositories for object_hash: None in SHA-256-only builds (521b3b2)
    • Make SHA-256-only lib tests really SHA-256-only (36aaf51)
    • Merge pull request #​3079 from krlvi/write-exists-check-no-pack-refresh (7a22948)
    • Merge pull request #​3065 from srijs/claude/project-thread-kr3hdl (0a49d46)
    • Don't look for new packs before writing an object (779b6c0)
    • Merge pull request #​3072 from juanibiapina/fix-status-filter-path (86d5fa6)
    • Merge pull request #​3068 from GitoxideLabs/fix-protect-access (38beb4d)
    • Respect section trust for filesystem path protections (7439578)
    • Merge pull request #​3064 from GitoxideLabs/various-improvements (8c513c5)
    • Add Submodule::resolved_url() for cloning (41cb46f)
    • Expose selected global attribute paths (a6f95af)
    • Provide safe interrupt setup and handle SIGHUP (840faa0)
    • Merge pull request #​3066 from GitoxideLabs/check-commit-graph (7540f69)
    • Merge pull request #​3037 from ameyypawar/gix-remote-default-branch (ad0202e)
    • Match Git clone reference handling and preserve offline defaults (1cc509b)
    • Match Git clone reference handling and preserve offline defaults (aa7eaea)
    • Add Remote::default_branch() to learn the default branch of a remote without connecting to it. (2ddcae4)
    • Merge pull request #​3057 from GitoxideLabs/worktree-add-windows (eae2fef)
    • Document and test partial clone checkouts after interruption (31185ff)
    • Merge pull request #​3058 from GitoxideLabs/worktree-improvements (79f3880)
    • Add worktree locking and a lock override that preserves changes (862e9c3)
    • Merge pull request #​3056 from GitoxideLabs/worktree-sparse-checkout (ca9eb08)
    • Merge pull request #​3053 from GitoxideLabs/various-improvements (2d8dcc4)
    • Enable core.longpaths when initializing linked-submodule fixtures (7edbf02)
    • Release gix-error v0.5.1, gix-utils v0.5.1 (6d1b686)
    • Resolve linked worktree submodules in their private Git directory (54234a6)
    • Merge pull request #​3052 from GitoxideLabs/various-improvements (2711f6a)
    • Honor replacement refs and bypass stale commit graphs (1b6d8da)
    • Remove the obsolete max-performance-safe feature (7467af0)
    • Make repository paths absolute without reloading (b94cd79)
    • Separate linked worktree registration from checkout (32a27be)
    • Worktree removal with late writes to both roots (e3b7670)
    • Merge pull request #​3048 from GitoxideLabs/new-release (5fccccf)

Configuration

📅 Schedule: (UTC)

  • Branch creation
    • At any time (no schedule defined)
  • Automerge
    • At any time (no schedule defined)

🚦 Automerge: Enabled.

♻ Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

👻 Immortal: This PR will be recreated if closed unmerged. Get config help if that's undesired.


  • If you want to rebase/retry this PR, check this box

This PR has been generated by Mend Renovate CLI.

@ferrlabs-renovate ferrlabs-renovate Bot added the security Security-related label Oct 24, 2026
@ferrlabs-renovate
ferrlabs-renovate Bot enabled auto-merge (squash) October 24, 2026 02:11
@ferrlabs-renovate

Copy link
Copy Markdown
Contributor Author

⚠️ Artifact update problem

Renovate failed to update an artifact related to this branch. You probably do not want to merge this PR as-is.

♻ Renovate will retry this branch, including artifacts, only when one of the following happens:

  • any of the package files in this branch needs updating, or
  • the branch becomes conflicted, or
  • you click the rebase/retry checkbox if found above, or
  • you rename this PR's title to start with "rebase!" to trigger it manually

The artifact failure details are included below:

File name: Cargo.lock
    Updating crates.io index
error: failed to select a version for `gix`.
    ... required by package `ferrflow v7.33.0 (/cache/repos/github/FerrLabs/FerrFlow)`
versions that meet the requirements `^0.90` are: 0.90.0

package `ferrflow` depends on `gix` with feature `max-performance-safe` but `gix` does not have that feature.
help: available features: anyhow, async-network-client, async-network-client-async-std, async-std, attributes, auto-chain-error, basic, blame, blob-diff, blocking-http-transport-curl, blocking-http-transport-curl-openssl, blocking-http-transport-curl-rustls, blocking-http-transport-reqwest, blocking-http-transport-reqwest-native-tls, blocking-http-transport-reqwest-rust-tls, blocking-http-transport-reqwest-rust-tls-trust-dns, blocking-network-client, cache-efficiency-debug, comfort, command, credentials, default, dirwalk, document-features, error-print-location, excludes, extras, gix-archive, gix-status, gix-worktree-stream, hp-tempfile-registry, index, interrupt, mailmap, max-control, max-performance, merge, notes, pack-cache-lru-dynamic, pack-cache-lru-static, parallel, prodash, progress-tree, progress-unit-bytes, progress-unit-human-numbers, regex, revision, revparse-regex, serde, sha1, sha256, status, tracing, tracing-detail, tree-error, worktree-archive, worktree-mutation, worktree-stream, zlib-sirocco


failed to select a version for `gix` which could resolve this conflict

@ferrfleet-interne ferrfleet-interne Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The security fix (GHSA-q54r-jf2p-rfr2) is worth taking, but this bump doesn't build as-is: one blocking finding inline. Automerge is on, so don't let it go through before CI is green.

Comment thread Cargo.toml Outdated

@ferrfleet-interne ferrfleet-interne Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The build break from my last review is fixed in 1277fa1 (thread resolved). One new blocking finding inline: max-control drops gix's object and pack caches, and max-performance is the upstream replacement. Automerge is on and Test/Build are still running, so this could merge as-is once they pass.

Comment thread Cargo.toml Outdated

@ferrfleet-interne ferrfleet-interne Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The max-control cache regression is fixed in 2378103: max-performance brings back gix's pack and object caches, and the lockfile adds no new crates, so no C code. No blocking findings left. Test, Build Release Binary and Coverage were still running when I checked.

@ferrlabs-renovate
ferrlabs-renovate Bot merged commit f2d0dcd into main Oct 24, 2026
33 checks passed
@ferrlabs-renovate
ferrlabs-renovate Bot deleted the renovate/crate-gix-vulnerability branch October 24, 2026 19:18
ferrflow Bot added a commit that referenced this pull request Oct 24, 2026
## [7.33.2] - 2026-10-24

### Bug Fixes

- fix(deps): update rust crate gix to 0.90 [security] (#1347)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

security Security-related

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant