已开启
Fix CVE-2023-30549;CVE-2025-65105 #28
Fix CVE-2023-30549;CVE-2025-65105 #28
已开启
byj0创建于 5月27日
共 3 个文件变更+365-1
@@ -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: 345+Release: 4
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
@@ -59,6 +59,8 @@ Patch12: 81.patch
59%endif59%endif
60Patch13: add-loong64-support-for-bbolt.patch60Patch13: add-loong64-support-for-bbolt.patch
61Patch14: openEuler-golang-1.21.4.patch61Patch14: openEuler-golang-1.21.4.patch
62+Patch15: backport-CVE-2023-30549.patch
63+Patch16: backport-CVE-2025-65105.patch
62 64
63# This Conflicts is in case someone tries to install the main apptainer65# This Conflicts is in case someone tries to install the main apptainer
64# package when an old singularity package is installed. An Obsoletes is on66# package when an old singularity package is installed. An Obsoletes is on
@@ -290,6 +292,8 @@ Provides the optional setuid-root portion of Apptainer.
290%patch -P 12 -p1292%patch -P 12 -p1
291%setup -n %{name}-%{package_version}293%setup -n %{name}-%{package_version}
292%patch -P 13 -p1294%patch -P 13 -p1
295+%patch -P 15 -p1
296+%patch -P 16 -p1
293%else297%else
294%autosetup -n %{name}-%{package_version}298%autosetup -n %{name}-%{package_version}
295%endif299%endif
@@ -435,6 +439,10 @@ fi
435%attr(4755, root, root) %{_libexecdir}/%{name}/bin/starter-suid439%attr(4755, root, root) %{_libexecdir}/%{name}/bin/starter-suid
436 440
437%changelog441%changelog
442+* Wed May 27 2026 baiyanjie <baiyanjie@kylinsec.com.cn> - 1.1.6-4
443+- Backport patch to fix CVE-2025-65105
444+- Backport patch to fix CVE-2023-30549
445+ 
438* Mon Dec 09 2024 zhengting <zhengting13@huawei.com> - 1.1.6-3446* Mon Dec 09 2024 zhengting <zhengting13@huawei.com> - 1.1.6-3
439- Patch golang verison fro openEuler 24.03447- Patch golang verison fro openEuler 24.03
440 448 
@@ -0,0 +1,299 @@
1+diff -Naur a/internal/pkg/runtime/engine/apptainer/prepare_linux.go b/internal/pkg/runtime/engine/apptainer/prepare_linux.go
2+--- a/internal/pkg/runtime/engine/apptainer/prepare_linux.go
3++++ b/internal/pkg/runtime/engine/apptainer/prepare_linux.go
4+@@ -150,7 +150,7 @@
5+ if err := e.prepareContainerConfig(starterConfig); err != nil {
6+ return err
7+ }
8+- if err := e.loadImages(starterConfig); err != nil {
9++ if err := e.loadImages(starterConfig, userNS); err != nil {
10+ return err
11+ }
12+ }
13+@@ -1131,12 +1131,12 @@
14+ return nil
15+ }
16+ 
17+-func (e *EngineOperations) loadImages(starterConfig *starter.Config) error {
18++func (e *EngineOperations) loadImages(starterConfig *starter.Config, userNS bool) error {
19+ images := make([]image.Image, 0)
20+ 
21+ // load rootfs image
22+ writable := e.EngineConfig.GetWritableImage()
23+- img, err := e.loadImage(e.EngineConfig.GetImage(), writable)
24++ img, err := e.loadImage(e.EngineConfig.GetImage(), writable, userNS)
25+ if err != nil {
26+ return err
27+ }
28+@@ -1236,7 +1236,13 @@
29+ return fmt.Errorf("while getting overlay partitions in %s: %s", img.Path, err)
30+ }
31+ for _, p := range overlays {
32+- if img.Writable && p.Type == image.EXT3 {
33++ if p.Type != image.EXT3 {
34++ continue
35++ }
36++ if !userNS && !e.EngineConfig.File.AllowSetuidMountExtfs {
37++ return fmt.Errorf("configuration disallows users from mounting SIF extfs partition in setuid mode, try --userns")
38++ }
39++ if img.Writable {
40+ writableOverlayPath = img.Path
41+ }
42+ }
43+@@ -1252,7 +1258,7 @@
44+ 
45+ switch e.EngineConfig.GetSessionLayer() {
46+ case apptainerConfig.OverlayLayer:
47+- overlayImages, err := e.loadOverlayImages(starterConfig, writableOverlayPath)
48++ overlayImages, err := e.loadOverlayImages(starterConfig, writableOverlayPath, userNS)
49+ if err != nil {
50+ return fmt.Errorf("while loading overlay images: %s", err)
51+ }
52+@@ -1264,7 +1270,7 @@
53+ }
54+ }
55+ 
56+- bindImages, err := e.loadBindImages(starterConfig)
57++ bindImages, err := e.loadBindImages(starterConfig, userNS)
58+ if err != nil {
59+ return fmt.Errorf("while loading data bind images: %s", err)
60+ }
61+@@ -1276,7 +1282,7 @@
62+ }
63+ 
64+ // loadOverlayImages loads overlay images.
65+-func (e *EngineOperations) loadOverlayImages(starterConfig *starter.Config, writableOverlayPath string) ([]image.Image, error) {
66++func (e *EngineOperations) loadOverlayImages(starterConfig *starter.Config, writableOverlayPath string, userNS bool) ([]image.Image, error) {
67+ images := make([]image.Image, 0)
68+ 
69+ for _, overlayImg := range e.EngineConfig.GetOverlayImage() {
70+@@ -1289,7 +1295,7 @@
71+ }
72+ }
73+ 
74+- img, err := e.loadImage(splitted[0], writableOverlay)
75++ img, err := e.loadImage(splitted[0], writableOverlay, userNS)
76+ if err != nil {
77+ if !image.IsReadOnlyFilesytem(err) {
78+ return nil, fmt.Errorf("failed to open overlay image %s: %s", splitted[0], err)
79+@@ -1325,7 +1331,7 @@
80+ }
81+ 
82+ // loadBindImages load data bind images.
83+-func (e *EngineOperations) loadBindImages(starterConfig *starter.Config) ([]image.Image, error) {
84++func (e *EngineOperations) loadBindImages(starterConfig *starter.Config, userNS bool) ([]image.Image, error) {
85+ images := make([]image.Image, 0)
86+ 
87+ binds := e.EngineConfig.GetBindPath()
88+@@ -1339,7 +1345,7 @@
89+ 
90+ sylog.Debugf("Loading data image %s", imagePath)
91+ 
92+- img, err := e.loadImage(imagePath, !binds[i].Readonly())
93++ img, err := e.loadImage(imagePath, !binds[i].Readonly(), userNS)
94+ if err != nil && !image.IsReadOnlyFilesytem(err) {
95+ return nil, fmt.Errorf("failed to load data image %s: %s", imagePath, err)
96+ }
97+@@ -1355,7 +1361,7 @@
98+ return images, nil
99+ }
100+ 
101+-func (e *EngineOperations) loadImage(path string, writable bool) (*image.Image, error) {
102++func (e *EngineOperations) loadImage(path string, writable bool, userNS bool) (*image.Image, error) {
103+ const delSuffix = " (deleted)"
104+ 
105+ imgObject, imgErr := image.Init(path, writable)
106+@@ -1413,11 +1419,17 @@
107+ if !e.EngineConfig.File.AllowContainerSquashfs {
108+ return nil, fmt.Errorf("configuration disallows users from running squashFS containers")
109+ }
110++ if !userNS && !e.EngineConfig.File.AllowSetuidMountSquashfs {
111++ return nil, fmt.Errorf("configuration disallows users from mounting squashFS in setuid mode, try --userns")
112++ }
113+ // Bare EXT3
114+ case image.EXT3:
115+ if !e.EngineConfig.File.AllowContainerExtfs {
116+ return nil, fmt.Errorf("configuration disallows users from running extFS containers")
117+ }
118++ if !userNS && !e.EngineConfig.File.AllowSetuidMountExtfs {
119++ return nil, fmt.Errorf("configuration disallows users from mounting extfs in setuid mode, try --userns")
120++ }
121+ // Bare sandbox directory
122+ case image.SANDBOX:
123+ if !e.EngineConfig.File.AllowContainerDir {
124+@@ -1425,6 +1437,9 @@
125+ }
126+ // SIF
127+ case image.SIF:
128++ if !userNS && !e.EngineConfig.File.AllowSetuidMountSquashfs {
129++ return nil, fmt.Errorf("configuration disallows users from mounting SIF squashFS partition in setuid mode, try --userns")
130++ }
131+ // Check if SIF contains an encrypted rootfs partition.
132+ // We don't support encryption for other partitions at present.
133+ encrypted, err := imgObject.HasEncryptedRootFs()
134+@@ -1435,6 +1450,9 @@
135+ if encrypted && !e.EngineConfig.File.AllowContainerEncrypted {
136+ return nil, fmt.Errorf("configuration disallows users from running encrypted SIF containers")
137+ }
138++ if encrypted && !userNS && !e.EngineConfig.File.AllowSetuidMountEncrypted {
139++ return nil, fmt.Errorf("configuration disallows users from mounting encrypted files in setuid mode")
140++ }
141+ // SIF without encryption - regardless of rootfs filesystem type
142+ if !encrypted && !e.EngineConfig.File.AllowContainerSIF {
143+ return nil, fmt.Errorf("configuration disallows users from running unencrypted SIF containers")
144+diff -Naur a/pkg/util/apptainerconf/config.go b/pkg/util/apptainerconf/config.go
145+--- a/pkg/util/apptainerconf/config.go
146++++ b/pkg/util/apptainerconf/config.go
147+@@ -76,46 +76,49 @@
148+ 
149+ // File describes the apptainer.conf file options
150+ type File struct {
151+- AllowSetuid bool `default:"yes" authorized:"yes,no" directive:"allow setuid"`
152+- AllowPidNs bool `default:"yes" authorized:"yes,no" directive:"allow pid ns"`
153+- ConfigPasswd bool `default:"yes" authorized:"yes,no" directive:"config passwd"`
154+- ConfigGroup bool `default:"yes" authorized:"yes,no" directive:"config group"`
155+- ConfigResolvConf bool `default:"yes" authorized:"yes,no" directive:"config resolv_conf"`
156+- MountProc bool `default:"yes" authorized:"yes,no" directive:"mount proc"`
157+- MountSys bool `default:"yes" authorized:"yes,no" directive:"mount sys"`
158+- MountDevPts bool `default:"yes" authorized:"yes,no" directive:"mount devpts"`
159+- MountHome bool `default:"yes" authorized:"yes,no" directive:"mount home"`
160+- MountTmp bool `default:"yes" authorized:"yes,no" directive:"mount tmp"`
161+- MountHostfs bool `default:"no" authorized:"yes,no" directive:"mount hostfs"`
162+- UserBindControl bool `default:"yes" authorized:"yes,no" directive:"user bind control"`
163+- EnableFusemount bool `default:"yes" authorized:"yes,no" directive:"enable fusemount"`
164+- EnableUnderlay bool `default:"yes" authorized:"yes,no" directive:"enable underlay"`
165+- MountSlave bool `default:"yes" authorized:"yes,no" directive:"mount slave"`
166+- AllowContainerSIF bool `default:"yes" authorized:"yes,no" directive:"allow container sif"`
167+- AllowContainerEncrypted bool `default:"yes" authorized:"yes,no" directive:"allow container encrypted"`
168+- AllowContainerSquashfs bool `default:"yes" authorized:"yes,no" directive:"allow container squashfs"`
169+- AllowContainerExtfs bool `default:"yes" authorized:"yes,no" directive:"allow container extfs"`
170+- AllowContainerDir bool `default:"yes" authorized:"yes,no" directive:"allow container dir"`
171+- AlwaysUseNv bool `default:"no" authorized:"yes,no" directive:"always use nv"`
172+- UseNvCCLI bool `default:"no" authorized:"yes,no" directive:"use nvidia-container-cli"`
173+- AlwaysUseRocm bool `default:"no" authorized:"yes,no" directive:"always use rocm"`
174+- SharedLoopDevices bool `default:"no" authorized:"yes,no" directive:"shared loop devices"`
175+- MaxLoopDevices uint `default:"256" directive:"max loop devices"`
176+- SessiondirMaxSize uint `default:"16" directive:"sessiondir max size"`
177+- MountDev string `default:"yes" authorized:"yes,no,minimal" directive:"mount dev"`
178+- EnableOverlay string `default:"try" authorized:"yes,no,try,driver" directive:"enable overlay"`
179+- BindPath []string `default:"/etc/localtime,/etc/hosts" directive:"bind path"`
180+- LimitContainerOwners []string `directive:"limit container owners"`
181+- LimitContainerGroups []string `directive:"limit container groups"`
182+- LimitContainerPaths []string `directive:"limit container paths"`
183+- AllowNetUsers []string `directive:"allow net users"`
184+- AllowNetGroups []string `directive:"allow net groups"`
185+- AllowNetNetworks []string `directive:"allow net networks"`
186+- RootDefaultCapabilities string `default:"full" authorized:"full,file,no" directive:"root default capabilities"`
187+- MemoryFSType string `default:"tmpfs" authorized:"tmpfs,ramfs" directive:"memory fs type"`
188+- CniConfPath string `directive:"cni configuration path"`
189+- CniPluginPath string `directive:"cni plugin path"`
190+- BinaryPath string `default:"$PATH:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" directive:"binary path"`
191++ AllowSetuid bool `default:"yes" authorized:"yes,no" directive:"allow setuid"`
192++ AllowPidNs bool `default:"yes" authorized:"yes,no" directive:"allow pid ns"`
193++ ConfigPasswd bool `default:"yes" authorized:"yes,no" directive:"config passwd"`
194++ ConfigGroup bool `default:"yes" authorized:"yes,no" directive:"config group"`
195++ ConfigResolvConf bool `default:"yes" authorized:"yes,no" directive:"config resolv_conf"`
196++ MountProc bool `default:"yes" authorized:"yes,no" directive:"mount proc"`
197++ MountSys bool `default:"yes" authorized:"yes,no" directive:"mount sys"`
198++ MountDevPts bool `default:"yes" authorized:"yes,no" directive:"mount devpts"`
199++ MountHome bool `default:"yes" authorized:"yes,no" directive:"mount home"`
200++ MountTmp bool `default:"yes" authorized:"yes,no" directive:"mount tmp"`
201++ MountHostfs bool `default:"no" authorized:"yes,no" directive:"mount hostfs"`
202++ UserBindControl bool `default:"yes" authorized:"yes,no" directive:"user bind control"`
203++ EnableFusemount bool `default:"yes" authorized:"yes,no" directive:"enable fusemount"`
204++ EnableUnderlay bool `default:"yes" authorized:"yes,no" directive:"enable underlay"`
205++ MountSlave bool `default:"yes" authorized:"yes,no" directive:"mount slave"`
206++ AllowContainerSIF bool `default:"yes" authorized:"yes,no" directive:"allow container sif"`
207++ AllowContainerEncrypted bool `default:"yes" authorized:"yes,no" directive:"allow container encrypted"`
208++ AllowContainerSquashfs bool `default:"yes" authorized:"yes,no" directive:"allow container squashfs"`
209++ AllowContainerExtfs bool `default:"yes" authorized:"yes,no" directive:"allow container extfs"`
210++ AllowContainerDir bool `default:"yes" authorized:"yes,no" directive:"allow container dir"`
211++ AllowSetuidMountEncrypted bool `default:"yes" authorized:"yes,no" directive:"allow setuid-mount encrypted"`
212++ AllowSetuidMountSquashfs bool `default:"yes" authorized:"yes,no" directive:"allow setuid-mount squashfs"`
213++ AllowSetuidMountExtfs bool `default:"no" authorized:"yes,no" directive:"allow setuid-mount extfs"`
214++ AlwaysUseNv bool `default:"no" authorized:"yes,no" directive:"always use nv"`
215++ UseNvCCLI bool `default:"no" authorized:"yes,no" directive:"use nvidia-container-cli"`
216++ AlwaysUseRocm bool `default:"no" authorized:"yes,no" directive:"always use rocm"`
217++ SharedLoopDevices bool `default:"no" authorized:"yes,no" directive:"shared loop devices"`
218++ MaxLoopDevices uint `default:"256" directive:"max loop devices"`
219++ SessiondirMaxSize uint `default:"16" directive:"sessiondir max size"`
220++ MountDev string `default:"yes" authorized:"yes,no,minimal" directive:"mount dev"`
221++ EnableOverlay string `default:"try" authorized:"yes,no,try,driver" directive:"enable overlay"`
222++ BindPath []string `default:"/etc/localtime,/etc/hosts" directive:"bind path"`
223++ LimitContainerOwners []string `directive:"limit container owners"`
224++ LimitContainerGroups []string `directive:"limit container groups"`
225++ LimitContainerPaths []string `directive:"limit container paths"`
226++ AllowNetUsers []string `directive:"allow net users"`
227++ AllowNetGroups []string `directive:"allow net groups"`
228++ AllowNetNetworks []string `directive:"allow net networks"`
229++ RootDefaultCapabilities string `default:"full" authorized:"full,file,no" directive:"root default capabilities"`
230++ MemoryFSType string `default:"tmpfs" authorized:"tmpfs,ramfs" directive:"memory fs type"`
231++ CniConfPath string `directive:"cni configuration path"`
232++ CniPluginPath string `directive:"cni plugin path"`
233++ BinaryPath string `default:"$PATH:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" directive:"binary path"`
234+ // SuidBinaryPath is hidden; it is not referenced below, and overwritten
235+ SuidBinaryPath string `directive:"suidbinary path"`
236+ MksquashfsProcs uint `default:"0" directive:"mksquashfs procs"`
237+@@ -127,6 +130,18 @@
238+ SystemdCgroups bool `default:"yes" authorized:"yes,no" directive:"systemd cgroups"`
239+ }
240+ 
241++// NOTE: if you think that we may want to change the default for any
242++// configuration parameter in the future, it is a good idea to conditionally
243++// insert a comment before the default setting when the setting is equal
244++// to the current default. That enables the defaults to get updated in
245++// a new release even if an administrator has changed one of the *other*
246++// settings. This gets around the problem of packagers such as rpm
247++// refusing to overwrite a configuration file if any change has been made.
248++// This technique is used for example in the "allow setuid-mount" options
249++// below. If a default is changed in a future release, both the default
250++// setting above and the expression for the conditional comment below need
251++// to change at the same time.
252++
253+ const TemplateAsset = `# APPTAINER.CONF
254+ # This is the global configuration file for Apptainer. This file controls
255+ # what the container is allowed to do on a particular host, and as a result
256+@@ -321,7 +336,9 @@
257+ # ALLOW CONTAINER ${TYPE}: [BOOL]
258+ # DEFAULT: yes
259+ # This feature limits what kind of containers that Apptainer will allow
260+-# users to use (note this does not apply for root).
261++# users to use (note this does not apply for root). Note that some of the
262++# same operations can be limited in setuid mode by the ALLOW SETUID-MOUNT
263++# feature below; both types need to be "yes" to be allowed.
264+ #
265+ # Allow use of unencrypted SIF containers
266+ allow container sif = {{ if eq .AllowContainerSIF true}}yes{{ else }}no{{ end }}
267+@@ -334,6 +351,32 @@
268+ allow container extfs = {{ if eq .AllowContainerExtfs true }}yes{{ else }}no{{ end }}
269+ allow container dir = {{ if eq .AllowContainerDir true }}yes{{ else }}no{{ end }}
270+ 
271++# ALLOW SETUID-MOUNT ${TYPE}: [BOOL]
272++# DEFAULT: yes, except no for extfs
273++# This feature limits what types of mounts that Apptainer will allow
274++# unprivileged users to use in setuid mode. Normally these operations
275++# require the elevated privileges of setuid mode, although Apptainer
276++# has unprivileged alternatives for squashfs and extfs. Note that some of
277++# the same operations can also be limited by the ALLOW CONTAINER feature
278++# above; both types need to be "yes" to be allowed.
279++#
280++# Allow mounting of SIF encryption (using the kernel device-mapper) in
281++# setuid mode
282++{{ if eq .AllowSetuidMountEncrypted true}}# {{ end }}allow setuid-mount encrypted = {{ if eq .AllowSetuidMountEncrypted true}}yes{{ else }}no{{ end }}
283++#
284++# Allow mounting of squashfs filesystem types in setuid mode, both inside and
285++# outside of SIF files
286++{{ if eq .AllowSetuidMountSquashfs true}}# {{ end }}allow setuid-mount squashfs = {{ if eq .AllowSetuidMountSquashfs true}}yes{{ else }}no{{ end }}
287++#
288++# Allow mounting of extfs filesystem types in setuid mode, both inside and
289++# outside of SIF files. WARNING: this filesystem type frequently has relevant
290++# CVEs that that take a very long time for vendors to patch because they are
291++# not considered to be High severity since normally unprivileged users do
292++# not have write access to the raw filesystem data. This is why this option
293++# defaults to "no". Change it at your own risk and consider using the
294++# LIMIT CONTAINER features above if you do.
295++{{ if eq .AllowSetuidMountExtfs false}}# {{ end }}allow setuid-mount extfs = {{ if eq .AllowSetuidMountExtfs true}}yes{{ else }}no{{ end }}
296++
297+ # ALLOW NET USERS: [STRING]
298+ # DEFAULT: NULL
299+ # Allow specified root administered CNI network configurations to be used by the
@@ -0,0 +1,57 @@
1+--- a/internal/pkg/security/security.go 2023-02-15 05:46:54.000000000 +0800
2++++ b/internal/pkg/security/security.go 2026-05-27 13:50:26.856910026 +0800
3+@@ -32,7 +32,7 @@
4+ return err
5+ }
6+ } else {
7+- sylog.Warningf("selinux is not enabled or supported on this system")
8++ return fmt.Errorf("selinux requested, but is not enabled or supported on this system")
9+ }
10+ } else if config.Process.ApparmorProfile != "" {
11+ if apparmor.Enabled() {
12+@@ -40,7 +40,7 @@
13+ return err
14+ }
15+ } else {
16+- sylog.Warningf("apparmor is not enabled or supported on this system")
17++ return fmt.Errorf("apparmor requested, but is not enabled or supported on this system")
18+ }
19+ }
20+ }
21+@@ -50,7 +50,7 @@
22+ return err
23+ }
24+ } else {
25+- sylog.Warningf("seccomp requested but not enabled, seccomp library is missing or too old")
26++ return fmt.Errorf("seccomp requested but not enabled, seccomp library is missing or too old")
27+ }
28+ }
29+ return nil
30+--- a/internal/pkg/security/apparmor/apparmor_supported.go 2023-02-15 05:46:54.000000000 +0800
31++++ b/internal/pkg/security/apparmor/apparmor_supported.go 2026-05-27 13:51:27.319543034 +0800
32+@@ -15,6 +15,8 @@
33+ "fmt"
34+ "io/ioutil"
35+ "os"
36++
37++ "golang.org/x/sys/unix"
38+ )
39+
40+ // Enabled returns whether AppArmor is enabled.
41+@@ -28,6 +30,16 @@
42+
43+ // LoadProfile loads the specified AppArmor profile.
44+ func LoadProfile(profile string) error {
45++ // Verify that /proc/self/attr/exec is on the real proc filesystem
46++ // to prevent containers from bypassing AppArmor by masking /proc.
47++ var st unix.Statfs_t
48++ if err := unix.Statfs("/proc/self/attr/exec", &st); err != nil {
49++ return fmt.Errorf("failed to verify proc filesystem: %w", err)
50++ }
51++ if st.Type != unix.PROC_SUPER_MAGIC {
52++ return fmt.Errorf("cannot set apparmor profile: /proc/self/attr/exec is not on procfs")
53++ }
54++
55+ f, err := os.OpenFile("/proc/self/attr/exec", os.O_WRONLY, 0)
56+ if err != nil {
57+ return err