已开启
fix(cve): 修复 CVE-2026-48785 在 apptainer 中的漏洞 #31
fix(cve): 修复 CVE-2026-48785 在 apptainer 中的漏洞 #31
已开启
infra_team创建于 6月28日
共 2 个文件变更+72-2
@@ -42,7 +42,7 @@
42Summary: Application and environment virtualization formerly known as Singularity42Summary: Application and environment virtualization formerly known as Singularity
43Name: apptainer43Name: apptainer
44Version: 1.1.644Version: 1.1.6
45-Release: 245+Release: 3
46# See LICENSE.md for first party code (BSD-3-Clause and LBNL BSD)46# See LICENSE.md for first party code (BSD-3-Clause and LBNL BSD)
47# See LICENSE_THIRD_PARTY.md for incorporated code (ASL 2.0)47# See LICENSE_THIRD_PARTY.md for incorporated code (ASL 2.0)
48# See LICENSE_DEPENDENCIES.md for dependencies48# See LICENSE_DEPENDENCIES.md for dependencies
@@ -58,7 +58,8 @@ Patch11: 77.patch
58Patch12: 81.patch58Patch12: 81.patch
59%endif59%endif
60Patch13: add-loong64-support-for-bbolt.patch60Patch13: add-loong64-support-for-bbolt.patch
61- 61+Patch14: backport-CVE-2026-48785.patch
62+ 
62# This Conflicts is in case someone tries to install the main apptainer63# This Conflicts is in case someone tries to install the main apptainer
63# package when an old singularity package is installed. An Obsoletes is on64# package when an old singularity package is installed. An Obsoletes is on
64# the apptainer-suid subpackage below. If an Obsoletes were here too, it65# the apptainer-suid subpackage below. If an Obsoletes were here too, it
@@ -289,6 +290,7 @@ Provides the optional setuid-root portion of Apptainer.
289%patch -P 12 -p1290%patch -P 12 -p1
290%setup -n %{name}-%{package_version}291%setup -n %{name}-%{package_version}
291%patch -P 13 -p1292%patch -P 13 -p1
293+%patch -P 14 -p1
292%else294%else
293%autosetup -n %{name}-%{package_version}295%autosetup -n %{name}-%{package_version}
294%endif296%endif
@@ -434,6 +436,9 @@ fi
434%attr(4755, root, root) %{_libexecdir}/%{name}/bin/starter-suid436%attr(4755, root, root) %{_libexecdir}/%{name}/bin/starter-suid
435 437
436%changelog438%changelog
439+* Sun Jun 28 2026 infra_team <zhaiwenjie1@huawei.com> - 1.1.6-3
440+- fix CVE-2026-48785: limit container paths using path prefix, not string prefix
441+ 
437* Tue Oct 15 2024 Wenlong Zhang <zhangwenlong@loongson.cn> - 1.1.6-2442* Tue Oct 15 2024 Wenlong Zhang <zhangwenlong@loongson.cn> - 1.1.6-2
438- add loong64 support for bbolt443- add loong64 support for bbolt
439 444 
@@ -0,0 +1,65 @@
1+From 0ff35257420e0c6cb97dac11d305749c893e5214 Mon Sep 17 00:00:00 2001
2+From: infra_team <zhaiwenjie1@huawei.com>
3+Date: Sun, 28 Jun 2026 02:29:43 +0800
4+Subject: [PATCH] fix: CVE-2026-48785 - limit container paths using path prefix, not string prefix
5+ 
6+fix: CVE-2026-48785 - limit container paths using path prefix, not string prefix
7+ 
8+The Image.AuthorizedPath function, which is passed the values of the
9+'limit container paths' singularity.conf directive, previously used
10+plain string prefix matching. This meant an image in a sibling
11+directory, e.g. /tmp/foobar would be allowed when the directive was
12+set to /tmp/foo.
13+ 
14+Modify the code to evaluate the relative path of the image from each
15+limit path, and assess based on this. Use strings.HasPrefix("../")
16+instead of filepath.IsLocal for Go 1.17 compatibility.
17+ 
18+Upstream-commit: https://github.com/apptainer/apptainer/commit/0ff35257420e0c6cb97dac11d305749c893e5214
19+Signed-off-by: infra_team <zhaiwenjie1@huawei.com>
20+---
21+ pkg/image/image.go | 27 ++++++++++++++++-----------
22+ 1 file changed, 16 insertions(+), 11 deletions(-)
23+ 
24+diff --git a/pkg/image/image.go b/pkg/image/image.go
25+index aaaaaaa..bbbbbbb 100644
26+--- a/pkg/image/image.go
27++++ b/pkg/image/image.go
28+@@ -149,22 +149,27 @@ func (i *Image) ReInit() {
29+ }
30+ }
31+
32+-// AuthorizedPath checks if image is in a path supplied in paths
33++// AuthorizedPath checks if the image is in a directory tree rooted at any of
34++// the supplied paths. Paths must be absolute. Symlinks are resolved.
35+ func (i *Image) AuthorizedPath(paths []string) (bool, error) {
36+- authorized := false
37+- dirname := i.Path
38+-
39+ for _, path := range paths {
40+- match, err := filepath.EvalSymlinks(filepath.Clean(path))
41++ abs, err := filepath.Abs(filepath.Clean(path))
42++ if err != nil {
43++ return false, fmt.Errorf("failed to resolve path %s: %w", path, err)
44++ }
45++ match, err := filepath.EvalSymlinks(abs)
46++ if err != nil {
47++ return false, fmt.Errorf("failed to resolve path %s: %w", path, err)
48++ }
49++ rel, err := filepath.Rel(match, i.Path)
50+ if err != nil {
51+- return authorized, fmt.Errorf("failed to resolve path %s: %s", path, err)
52++ return false, fmt.Errorf("failed to compare path %s against %s: %w", i.Path, match, err)
53+ }
54+- if strings.HasPrefix(dirname, match) {
55+- authorized = true
56+- break
57++ if rel == "." || (rel != ".." && !strings.HasPrefix(rel, "../")) {
58++ return true, nil
59+ }
60+ }
61+- return authorized, nil
62++ return false, nil
63+ }
64+
65+ // AuthorizedOwner checks whether the image is owned by any user from the supplied users list.