osec-2025-01
Vulnerability from osv_ocaml
Background
Albatross-console reads the console output from multiple unikernel tenders (solo5-hvt). This console output can be retrieved using albatross-client.
The console protocol is fairly simple: the unikernel invokes a PUTS hypercall, which sends arbitrary bytes of given length to the unikernel tender (host, typically solo5-hvt), which writes them to a file descriptor.
albatross_console reads this output, and assumes it will be newline delimited, and keeps at most 1024 lines.
Problem description
This helps guard against unlimited memory usage from runaway/long running unikernels, however it doesn't guard against malicious (or buggy) unikernels.
The problem is this line in albatross_console:
let rec loop () =
Lwt_io.read_line channel
Unfortunately Lwt_io.read_line doesn't take a parameter to limit the size of the line that is read, so it is very easy for a unikernel to exhaust the memory of albatross_console: all it needs to do is to write a lot of bytes without ever writing a newline.
Tested with the Debian packages, but confirmed the above code to be present in latest master too:
$ /usr/libexec/albatross/albatross-console --version
version v2.3.0-9-g5b14787 protocol version 5
Impact
A typical attack will look like this in albatross_console's logs:
Jun 07 16:41:18 ubuntu22 albatross-console[13721]: albatross-console:
[WARNING] disconnected
Jun 07 16:41:42 ubuntu22 albatross-console[13721]: albatross-console:
[ERROR] exception Unix.Unix_error(Unix.EBADF, "check_descriptor", "")
while writing
Jun 07 16:42:09 ubuntu22 albatross-console[13721]: albatross-console:
[WARNING] disconnected
Jun 07 16:44:07 ubuntu22 albatross-console[13721]: albatross-console:
[ERROR] :mine error while reading Out of memory
Jun 07 16:55:43 ubuntu22 albatross-console[13721]: albatross-console:
[ERROR] exception Unix.Unix_error(Unix.EBADF, "check_descriptor", "")
while writing
Jun 07 16:57:20 ubuntu22 albatross-console[13721]: albatross-console:
[ERROR] exception Unix.Unix_error(Unix.EPIPE, "send", "") while writing
Jun 07 16:57:20 ubuntu22 albatross-console[13721]: albatross-console:
[ERROR] exception Unix.Unix_error(Unix.EPIPE, "send", "") while writing
While the attack is happening albatross_console will also be very slow to react to the console of other unikernels, and will use increasing amounts of memory until an out of memory exception is raised.
Albatross_console stays running in my tests (obviously the bad unikernel will no longer have a functioning console, but that is to be expected).
However using so much memory can have an effect on other services running on the host.
Workaround
Set MemoryMax=1G in the service file of albatross_console to limit the amount of memory a runaway console can use, so at least it fails sooner.
However in practice this just keeps albatross_console using 100% CPU without raising an Out of Memory exception, although it stays within 1G of memory.
There is no known workaround for the DoS attack, in theory Lwt should be switching promises when another one becomes runnable, but it doesn't provide fairness mechanisms.
Solution
Use albatross in version 2.5.0 or above. Another solution is to apply the patch https://github.com/robur-coop/albatross/commit/d01805796ec710691a701c01ed3f0e4cd284a161 manually.
Binary builds of version 2.5.0 are available from https://builds.robur.coop
Timeline
- 2025-06-07: issue discovered by Edwin Török as part of the HACKSAT25 challenge
- 2025-06-07: initial email sent to hacksat@parsimoni.co
- 2025-06-11: initial email sent to albatross maintainer
- 2025-08-15: albatross 2.5.0 released with the patch
{
"affected": [
{
"ecosystem_specific": {
"opam_constraint": "albatross {\u003c \"2.5.0\"}"
},
"package": {
"ecosystem": "opam",
"name": "albatross",
"purl": "pkg:opam/albatross"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "2.5.0"
}
],
"type": "ECOSYSTEM"
},
{
"events": [
{
"introduced": "0"
},
{
"fixed": "d01805796ec710691a701c01ed3f0e4cd284a161"
}
],
"repo": "https://github.com/robur-coop/albatross",
"type": "GIT"
}
],
"versions": [
"1.0.1",
"1.1.0",
"1.1.1",
"1.2.0",
"1.3.0",
"1.3.1",
"1.4.0",
"1.4.1",
"1.4.2",
"1.4.3",
"1.5.0",
"1.5.1",
"1.5.2",
"1.5.3",
"1.5.4",
"1.5.5",
"1.5.6",
"2.0.0",
"2.1.0",
"2.2.0",
"2.3.0",
"2.4.0",
"2.4.1"
]
}
],
"credits": [
{
"name": "Edwin T\u00f6r\u00f6k",
"type": "REPORTER"
},
{
"name": "Reynir Bj\u00f6rnsson",
"type": "REMEDIATION_DEVELOPER"
},
{
"name": "Hannes Mehnert",
"type": "REMEDIATION_REVIEWER"
}
],
"database_specific": {
"cwe": [
"CWE-770"
],
"human_link": "https://github.com/ocaml/security-advisories/tree/main/advisories/2025/OSEC-2025-01.md",
"osv": "https://github.com/ocaml/security-advisories/tree/generated-osv/2025/OSEC-2025-01.json"
},
"details": "## Background\n\nAlbatross-console reads the console output from multiple unikernel tenders (solo5-hvt). This console output can be retrieved using albatross-client.\n\nThe console protocol is fairly simple: the unikernel invokes a PUTS hypercall, which sends arbitrary bytes of given length to the unikernel tender (host, typically solo5-hvt), which writes them to a file descriptor.\n\nalbatross_console reads this output, and assumes it will be newline delimited, and keeps at most 1024 lines.\n\n\n## Problem description\n\nThis helps guard against unlimited memory usage from runaway/long running unikernels, however it doesn\u0027t guard against malicious (or buggy) unikernels.\n\nThe problem is this line in albatross_console:\n\n```\nlet rec loop () =\n Lwt_io.read_line channel\n```\n\nUnfortunately Lwt_io.read_line doesn\u0027t take a parameter to limit the size of the line that is read, so it is very easy for a unikernel to exhaust the memory of albatross_console: all it needs to do is to write a lot of bytes without ever writing a newline.\n\nTested with the Debian packages, but confirmed the above code to be present in latest master too:\n```\n$ /usr/libexec/albatross/albatross-console --version\nversion v2.3.0-9-g5b14787 protocol version 5\n```\n\n## Impact\n\nA typical attack will look like this in albatross_console\u0027s logs:\n```\nJun 07 16:41:18 ubuntu22 albatross-console[13721]: albatross-console:\n[WARNING] disconnected\nJun 07 16:41:42 ubuntu22 albatross-console[13721]: albatross-console:\n[ERROR] exception Unix.Unix_error(Unix.EBADF, \"check_descriptor\", \"\")\nwhile writing\nJun 07 16:42:09 ubuntu22 albatross-console[13721]: albatross-console:\n[WARNING] disconnected\nJun 07 16:44:07 ubuntu22 albatross-console[13721]: albatross-console:\n[ERROR] :mine error while reading Out of memory\nJun 07 16:55:43 ubuntu22 albatross-console[13721]: albatross-console:\n[ERROR] exception Unix.Unix_error(Unix.EBADF, \"check_descriptor\", \"\")\nwhile writing\nJun 07 16:57:20 ubuntu22 albatross-console[13721]: albatross-console:\n[ERROR] exception Unix.Unix_error(Unix.EPIPE, \"send\", \"\") while writing\nJun 07 16:57:20 ubuntu22 albatross-console[13721]: albatross-console:\n[ERROR] exception Unix.Unix_error(Unix.EPIPE, \"send\", \"\") while writing\n```\n\nWhile the attack is happening albatross_console will also be very slow to react to the console of other unikernels, and will use increasing amounts of memory until an out of memory exception is raised.\n\nAlbatross_console stays running in my tests (obviously the bad unikernel will no longer have a functioning console, but that is to be expected).\n\nHowever using so much memory can have an effect on other services running on the host.\n\n## Workaround\n\nSet MemoryMax=1G in the service file of albatross_console to limit the amount of memory a runaway console can use, so at least it fails sooner.\n\nHowever in practice this just keeps albatross_console using 100% CPU without raising an Out of Memory exception, although it stays within 1G of memory.\n\nThere is no known workaround for the DoS attack, in theory Lwt should be switching promises when another one becomes runnable, but it doesn\u0027t provide fairness mechanisms.\n\n## Solution\n\nUse albatross in version 2.5.0 or above. Another solution is to apply the patch https://github.com/robur-coop/albatross/commit/d01805796ec710691a701c01ed3f0e4cd284a161 manually.\n\nBinary builds of version 2.5.0 are available from https://builds.robur.coop\n\n## Timeline\n\n- 2025-06-07: issue discovered by Edwin T\u00f6r\u00f6k as part of the HACKSAT25 challenge\n- 2025-06-07: initial email sent to hacksat@parsimoni.co\n- 2025-06-11: initial email sent to albatross maintainer\n- 2025-08-15: albatross 2.5.0 released with the patch",
"id": "OSEC-2025-01",
"modified": "2026-01-13T12:00:00Z",
"published": "2025-08-15T00:18:22Z",
"references": [
{
"type": "ADVISORY",
"url": "https://lists.xenproject.org/archives/html/mirageos-devel/2025-08/msg00000.html"
}
],
"schema_version": "1.7.4",
"severity": [
{
"score": "CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:C/C:N/I:N/A:H",
"type": "CVSS_V3"
}
],
"summary": "Albatross console out of memory"
}
Sightings
| Author | Source | Type | Date |
|---|
Nomenclature
- Seen: The vulnerability was mentioned, discussed, or observed by the user.
- Confirmed: The vulnerability has been validated from an analyst's perspective.
- Published Proof of Concept: A public proof of concept is available for this vulnerability.
- Exploited: The vulnerability was observed as exploited by the user who reported the sighting.
- Patched: The vulnerability was observed as successfully patched by the user who reported the sighting.
- Not exploited: The vulnerability was not observed as exploited by the user who reported the sighting.
- Not confirmed: The user expressed doubt about the validity of the vulnerability.
- Not patched: The vulnerability was not observed as successfully patched by the user who reported the sighting.