Cordial 0.5.2 — the Flatpak works
The Flatpak works. It never had, on any machine, and six separate faults
stood between the packaged build and a running client.
Every one was invisible from cargo run. That is the reason they survived: the
packaged build is a different machine — different libc, different filesystem
view, none of the session services — and nothing here had ever been launched by
a person from an installed package until today.
Install
flatpak remote-add --if-not-exists cordial \
https://luohoa97.github.io/cordial/cordial.flatpakrepo
flatpak install cordial io.github.luohoa97.CordialYou supply the Roblox build yourself; Cordial ships none. The setup dialog will
point you at the easiest way to get one.
The blocker: the linker was built with PATH_MAX=256
third_party/mcpelauncher-linker/CMakeLists.txt defines it, shrinking seven
char buf[PATH_MAX] buffers across four linker files — while the realpath and
readlink they are handed to are the host's, entitled to write 4096. The
client aborted at linker init:
*** buffer overflow detected ***: terminated
and the call site says the rest — mov $0x100,%edx into __realpath_chk.
The host build is the less trustworthy of the two results here. It makes the
same calls through plain realpath@plt with zero __realpath_chk in the
binary — unfortified, never checked. It has carried the same undersized buffers
all along, and a resolved path over 255 characters smashes that frame today with
nothing to report it. The Flatpak's runtime fortifies these calls, so it was the
first thing to notice a latent overflow rather than the thing that caused one.
The other five
- The sandbox could not see the Roblox build its own dialog pointed at. "No
Roblox build found" named the exact path it looked in, and that path held a
97 MBbase.apkthe sandbox had no grant for. The instructions were right,
the user followed them, and the program said they had not. - The session was being written to disk. With no
org.freedesktop.secrets
grant, the runtime found no service and fell back to a 0600 file — announcing
it plainly. The install route the README recommends was the one build that
kept the session off the keyring. - Every connection read as metered, because there was no system bus at all.
Deliberately not fixed with the portal:NetworkMonitorneeds no grant
and was the obvious answer, but it reportsmeteredas a boolean where
NMMeteredhas five values, and only an explicitNOmay enable a background
download here. Going through it would have quietly rewritten that rule while
looking tidier. - AT-SPI needed two grants, and one alone would have been a lie. The name
makesGetAddressanswer — with a socket path that is not in the sandbox. So
granting only the name moves the failure from a lookup to a connect and looks
like a fix. - CI could hang the queue indefinitely. No
timeout-minutes, so GitHub's
six-hour default applied while the concurrency group allows one run at a time.
A run stuck inapt-getheld everything behind it.
GameMode is not fixed and is not claimed to be. The name resolves now, so
the grant took; gamemoded declines to register the sandboxed process with
rc -1. Different problem, named as one.
Measured
Clean install from the published remote, local override reset so only the
package's own permissions applied:
[secrets] the session is kept in the desktop secret service
[accessibility] connected to the AT-SPI bus as :1.559
[android] display backend: Wayland
LOADED in 25ms
[android] vulkan: swapchain present mode FIFO -> MAILBOX
[roblox] datamodel notification: APP_READY Landing
cargo test --workspace: 460 passed, 0 failed.
Correcting 0.5.1
That release said the installed shell opening a window had not been observed,
and offered a name-collision hypothesis for why it exited immediately. The
hypothesis was right and it is now observed — the launcher runs, draws its
window, finds a Roblox build and starts the client. The earlier exits were a
GApplication with a fixed id handing off to a development build that already
held the name: the single-instance mechanism working, not a fault.
Still broken
Text fields do not paint while focused. The pointer is not captured in first
person. X11 fullscreen segfaults. Web views are unimplemented. Audio initialises
and then fails with FMOD_ERR_OUTPUT_INIT.
There is no script execution, hooking or memory access — those are absent from
the API rather than disabled.