There are a couple solutions, with tradeoffs of course. It's important to remember that this isn't merely a technical problem. Some choices can be judged by human reviewers to be violating policy.
The obvious solution is to use isolatedProcess, the isolated_app SELinux domain, just as web browsers do. The restriction on executable code "does not apply to code that runs in a virtual machine and has limited access to Android APIs". Of course everything depends on what "limited access" means. Filtering out paths that start with "/../this-is-a-limitation/../" probably isn't enough.
Another solution is to ship all of the executable bytes. Turn an entire Linux distribution into something like busybox. It would be possible to exclude the non-executable pages of memory, shipping those separately as code-free ELF files. Installing programs would work the normal way, except that the .text sections would be empty holes in the files. As long as the mremap system call works, a loader should be easy to implement.
The obvious solution is to use isolatedProcess, the isolated_app SELinux domain, just as web browsers do. The restriction on executable code "does not apply to code that runs in a virtual machine and has limited access to Android APIs". Of course everything depends on what "limited access" means. Filtering out paths that start with "/../this-is-a-limitation/../" probably isn't enough.
Another solution is to ship all of the executable bytes. Turn an entire Linux distribution into something like busybox. It would be possible to exclude the non-executable pages of memory, shipping those separately as code-free ELF files. Installing programs would work the normal way, except that the .text sections would be empty holes in the files. As long as the mremap system call works, a loader should be easy to implement.