Skip to content

Cordial 0.5.2 — the Flatpak works

Choose a tag to compare

@luohoa97 luohoa97 released this 05 Aug 11:19
· 431 commits to main since this release

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.Cordial

You 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 MB base.apk the 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: NetworkMonitor needs no grant
    and was the obvious answer, but it reports metered as a boolean where
    NMMetered has five values, and only an explicit NO may 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
    makes GetAddress answer — 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 in apt-get held 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.