Open
fix(cve): 修复 CVE-2026-88624 在 opencode 中的漏洞 #16
infra_teamAdd on Sep 26
fix(cve): 修复 CVE-2026-88624 在 opencode 中的漏洞 #16
Open
Total: 2 files changed+64-1
| @@ -0,0 +1,54 @@ | |||
| 1 | +From f8aef48d21618206c1c60f89099363f8fda424b2 Mon Sep 17 00:00:00 2001 | ||
| 2 | +From: infra_team <zhaiwenjie1@huawei.com> | ||
| 3 | +Date: Fri, 25 Sep 2026 17:23:39 +0000 | ||
| 4 | +Subject: [PATCH] fix: CVE-2026-88624 - enforce worktree path containment in | ||
| 5 | + Worktree.remove | ||
| 6 | + | ||
| 7 | +Worktree.remove() cleaned up any existing directory that was not a | ||
| 8 | +registered git worktree without checking whether that directory lived | ||
| 9 | +inside the project worktree. A caller-supplied path pointing anywhere on | ||
| 10 | +the filesystem was passed to cleanDirectory(), which runs | ||
| 11 | +fsp.rm(target, { recursive: true, force: true }), yielding an arbitrary | ||
| 12 | +recursive directory deletion primitive (CWE-22). | ||
| 13 | + | ||
| 14 | +Only run stopFsmonitor()/cleanDirectory() when the canonical directory | ||
| 15 | +is strictly inside the canonical project worktree and is not the | ||
| 16 | +worktree itself. Unregistered paths outside the project worktree are now | ||
| 17 | +skipped instead of being deleted. | ||
| 18 | + | ||
| 19 | +Upstream-commit: https://github.com/advisories/GHSA-fx2r-fm89-x94v | ||
| 20 | +Signed-off-by: infra_team <zhaiwenjie1@huawei.com> | ||
| 21 | +--- | ||
| 22 | + packages/opencode/src/worktree/index.ts | 7 +++++-- | ||
| 23 | + 1 file changed, 5 insertions(+), 2 deletions(-) | ||
| 24 | + | ||
| 25 | +diff --git a/packages/opencode/src/worktree/index.ts b/packages/opencode/src/worktree/index.ts | ||
| 26 | +index a0c43ed..0028498 100644 | ||
| 27 | +--- a/packages/opencode/src/worktree/index.ts | ||
| 28 | ++++ b/packages/opencode/src/worktree/index.ts | ||
| 29 | +@@ -392,9 +392,10 @@ const layer: Layer.Layer< | ||
| 30 | + } | ||
| 31 | + | ||
| 32 | + const directory = yield* canonical(input.directory) | ||
| 33 | ++ const primary = yield* canonical(ctx.worktree) | ||
| 34 | + | ||
| 35 | + // Preserve the loaded path casing for the store cache; `directory` is lowercased on Windows. | ||
| 36 | +- if (directory !== (yield* canonical(ctx.worktree))) yield* store.disposeDirectory(input.directory) | ||
| 37 | ++ if (directory !== primary) yield* store.disposeDirectory(input.directory) | ||
| 38 | + | ||
| 39 | + const list = yield* git(["worktree", "list", "--porcelain"], { cwd: ctx.worktree }) | ||
| 40 | + if (list.code !== 0) { | ||
| 41 | +@@ -406,7 +407,9 @@ const layer: Layer.Layer< | ||
| 42 | + | ||
| 43 | + if (!entry?.path) { | ||
| 44 | + const directoryExists = yield* fs.exists(directory).pipe(Effect.orDie) | ||
| 45 | +- if (directoryExists) { | ||
| 46 | ++ // Only clean up directories that live inside the project worktree; | ||
| 47 | ++ // an unregistered path outside of it is not ours to delete (CVE-2026-88624). | ||
| 48 | ++ if (directoryExists && directory !== primary && directory.startsWith(primary + pathSvc.sep)) { | ||
| 49 | + yield* stopFsmonitor(directory) | ||
| 50 | + yield* cleanDirectory(directory) | ||
| 51 | + } | ||
| 52 | +-- | ||
| 53 | +2.39.5 | ||
| 54 | + | ||
| @@ -28,7 +28,7 @@ | |||
| 28 | 28 | ||
| 29 | Name: opencode | 29 | Name: opencode |
| 30 | Version: 1.17.13 | 30 | Version: 1.17.13 |
| 31 | -Release: 2 | 31 | +Release: 3 |
| 32 | Summary: The open source coding agent. | 32 | Summary: The open source coding agent. |
| 33 | 33 | ||
| 34 | License: MIT | 34 | License: MIT |
| @@ -46,6 +46,9 @@ Source5: https://nodejs.org/dist/v%{nodejs_version}/node-v%{nodejs_versio | |||
| 46 | # Desktop .desktop files and icons extracted from official upstream RPMs. | 46 | # Desktop .desktop files and icons extracted from official upstream RPMs. |
| 47 | Source6: opencode-assets-%{version}.tar.gz | 47 | Source6: opencode-assets-%{version}.tar.gz |
| 48 | 48 | ||
| 49 | +# fix CVE-2026-88624: enforce worktree path containment in Worktree.remove | ||
| 50 | +Patch0: backport-CVE-2026-88624-worktree-path-containment.patch | ||
| 51 | + | ||
| 49 | ExclusiveArch: aarch64 x86_64 | 52 | ExclusiveArch: aarch64 x86_64 |
| 50 | 53 | ||
| 51 | BuildRequires: findutils | 54 | BuildRequires: findutils |
| @@ -84,6 +87,7 @@ rm -rf %{name}-%{version} | |||
| 84 | mkdir -p %{name}-%{version} | 87 | mkdir -p %{name}-%{version} |
| 85 | tar -xzf %{_sourcedir}/%{source_archive} --strip-components=1 -C %{name}-%{version} | 88 | tar -xzf %{_sourcedir}/%{source_archive} --strip-components=1 -C %{name}-%{version} |
| 86 | cd %{name}-%{version} | 89 | cd %{name}-%{version} |
| 90 | +%patch0 -p1 | ||
| 87 | 91 | ||
| 88 | %build | 92 | %build |
| 89 | cd %{name}-%{version} | 93 | cd %{name}-%{version} |
| @@ -339,6 +343,11 @@ fi | |||
| 339 | %{_datadir}/icons/hicolor/*/apps/* | 343 | %{_datadir}/icons/hicolor/*/apps/* |
| 340 | 344 | ||
| 341 | %changelog | 345 | %changelog |
| 346 | +* Sat Sep 26 2026 infra_team <zhaiwenjie1@huawei.com> - 1.17.13-3 | ||
| 347 | +- fix CVE-2026-88624: enforce worktree path containment in Worktree.remove | ||
| 348 | + so unregistered directories outside the project worktree are no longer | ||
| 349 | + recursively deleted | ||
| 350 | + | ||
| 342 | * Thu Sep 17 2026 hongyu-shi <shywzt@iCloud.com> - 1.17.13-2 | 351 | * Thu Sep 17 2026 hongyu-shi <shywzt@iCloud.com> - 1.17.13-2 |
| 343 | - Ship the aarch64 and x86_64 variants of the vendored node_modules and Node.js | 352 | - Ship the aarch64 and x86_64 variants of the vendored node_modules and Node.js |
| 344 | tarballs as separate Source entries with fixed names so the SRPM contains the | 353 | tarballs as separate Source entries with fixed names so the SRPM contains the |