proot-me / proot-rs Goto Github PK
View Code? Open in Web Editor NEWRust implementation of PRoot, a ptrace-based sandbox
License: GNU General Public License v3.0
Rust implementation of PRoot, a ptrace-based sandbox
License: GNU General Public License v3.0
For the manual page, we can consider automatic generation with the help of a template in build.rs, like this
Originally posted by @KB5201314 in #7 (comment)
./proot-rs -V
proot-rs
./proot-rs --version
proot-rs
Tools
Also, per conversation with @jyn514,
run clippy before compiling, otherwise it won't output anything, it's an ongoing bug.
$ cargo build --release
Compiling proot-rs v0.1.0 (/home/joshua/Documents/Programming/unchanged/proot-rs)
error: failed to run custom build command for `proot-rs v0.1.0 (/home/joshua/Documents/Programming/unchanged/proot-rs)`
Caused by:
process didn't exit successfully: `/home/joshua/Documents/Programming/unchanged/proot-rs/target/release/build/proot-rs-101da09efcaf31a7/build-script-build_loader` (exit code: 101)
...
running: "cc" "-O3" "-ffunction-sections" "-fdata-sections" "-fPIC" "-m64" "-static" "-nostdlib" "-o" "src/kernel/execve/loader/binary_loader_exe" "src/kernel/execve/loader/loader.c"
cargo:warning=/tmp/ccaDws1D.o: In function `_start':
cargo:warning=loader.c:(.text._start+0x2a1): undefined reference to `memset'
cargo:warning=loader.c:(.text._start+0x2ce): undefined reference to `memset'
cargo:warning=loader.c:(.text._start+0x365): undefined reference to `memset'
cargo:warning=collect2: error: ld returned 1 exit status
exit code: 1
Looking at src/build_loader.rs
, I think this is because you're compiling with -nostdlib
. Since memset is in the stdlib, you can't use memset.
The effect of --bind
is not reflected in the result of getdents64()
, which can cause some differences in the results of ls -la
.
What --bind
does is basically overwrite one path on top of another. proot-rs
is emulating this behavior, so we need to filter the entries in result of getdents64()
to ensure that they do not contain information about entries that under the overwritten. As far as I know original proot also has this problem.
The impact of this issue is not very significant, even a little harsh, so I marked it as an enhancement
I mean I would edit loader-shim/src/main.rs if I knew what was going on there but it uses handwritten assembly.
Remaining steps for the bare minimum (single-tracee, no glue, no extensions, no ptrace-translation, no unix-socket translation, no qemu, -r/-R, -w and -b cli options only, no seccomp, and x86-64 with 64bits programs only):
src/register
)src/filesystem
)src/kernel/execve
)src/kernel/standard
)Most of these are pretty much straightforward once the basic functions are covered (translate_sysarg
).
Though there are a lot of them, and they all need to be unit/ci tested.
src/cli
)This is the first step for a usable proot-rs.
After being able to create the rootfs, we have to get the first simple program (/bin/sleep) to run and exit successfully.
This task is divided into three main parts:
After #32 bats-core is resolved, we need to write integration tests using bats-core
.
Since we can already run single programs, we can set up some tests that run proot-rs binaries directly.
shUnit2 is also great, but it seems to be better suited for testing shell scripts. And bats-core claims to provides a simple way to verify a UNIX programs. that's also our purpose.
After this, also try "backport" integration tests to the original proot.
The current implementation is written for Linux x86_64 and lacks support for android and arm/aarch64.
These issues need to be resolved:
sc
), some libraries behave differently on the arm/aarch64 architecture (e.g. missing libc::user_regs_struct
)I changed it from
.
to/
, because current work dir (.
) may be outside the new root(/
), and it is hard to detranslate path.
.Furthermore, the default cwd for
chroot
is also/
instead of.
.sudo chroot / /bin/sh -c "pwd -P" # The output is `/`
Originally posted by @KB5201314 in #28 (comment)
proot-rs is currently not aware of the / at the end of the path during path translation. This causes the behavior of ls to be inconsistent with that on host.
inside guestfs:
This issue and #40 are both related to handling trailing slash
Resources:
It's worth mentioning that, in the process of translating rename(), I found that the original proot also changed tracee's cwd.
https://github.com/proot-me/proot/blob/7ac33878f95237401b9759db853a6b8c37899675/src/syscall/exit.c#L296
Specifically, if the path being rename() is the same as current tracee's cwd, then it will update the current tracee's cwd filed to the new path.
I think this is something similar to "what happens when you move an open file". The handling in orignal proot is a very hack method (that is, updating the cwd after rename() syscall ), so I'm not implementing it in proot-rs at the moment, just leaving a TODO marker here.
It tries to emulate a phenomenon in the Linux filesystem. But I think it's hacky for several reasons.
- it may conflict with the --bind function of proot-rs in some cases. For example, if /foo is bound to /bar and tracee's cwd is "/bar", it won't sense rename("/foo", "/foo2") because "/foo" is not a cwd prefix. So this hack will be bypassed.
- In addition, in the original proot only the cwd of the tracee calling rename() is checked. However, it is possible that one tracee's rename() modifies the prefix of another tracee's cwd, but is not sensed by proot.
Yes, but I haven't actually found a document that defines this behavior so far, not in lwn, and seemingly not in POSIX. So I think we can let it go for now.
docker-compose run proot-rs-sdk /bin/bash
USE_CROSS=true CARGO_BUILD_TARGET=x86_64-unknown-linux-musl cargo make build
[cargo-make] INFO - cargo make 0.35.0
[cargo-make] INFO - Build File: Makefile.toml
[cargo-make] INFO - Task: build
[cargo-make] INFO - Profile: development
[cargo-make] INFO - Running Task: legacy-migration
[cargo-make] INFO - Running Task: build-loader
info: downloading component 'rust-src'
info: installing component 'rust-src'
error: want driver overlay2, got devicemapper
note: run with `RUST_BACKTRACE=1` for a backtrace
[cargo-make] ERROR - Error while executing command, exit code: 1
[cargo-make] WARN - Build Failed.
root@452f7025f91d:/usr/src/proot-rs# USE_CROSS=true CARGO_BUILD_TARGET=x86_64-unknown-linux-gnu cargo make build
[cargo-make] INFO - cargo make 0.35.0
[cargo-make] INFO - Build File: Makefile.toml
[cargo-make] INFO - Task: build
[cargo-make] INFO - Profile: development
[cargo-make] INFO - Running Task: legacy-migration
[cargo-make] INFO - Running Task: build-loader
error: want driver overlay2, got devicemapper
note: run with `RUST_BACKTRACE=1` for a backtrace
[cargo-make] ERROR - Error while executing command, exit code: 1
[cargo-make] WARN - Build Failed.
root@452f7025f91d:/usr/src/proot-rs# USE_CROSS=true CARGO_BUILD_TARGET=x86_64-linux-android cargo make build
[cargo-make] INFO - cargo make 0.35.0
[cargo-make] INFO - Build File: Makefile.toml
[cargo-make] INFO - Task: build
[cargo-make] INFO - Profile: development
[cargo-make] INFO - Running Task: legacy-migration
[cargo-make] INFO - Running Task: build-loader
error: want driver overlay2, got devicemapper
note: run with `RUST_BACKTRACE=1` for a backtrace
[cargo-make] ERROR - Error while executing command, exit code: 1
[cargo-make] WARN - Build Failed.
root@452f7025f91d:/usr/src/proot-rs# USE_CROSS=true CARGO_BUILD_TARGET=i686-unknown-linux-musl cargo make build
[cargo-make] INFO - cargo make 0.35.0
[cargo-make] INFO - Build File: Makefile.toml
[cargo-make] INFO - Task: build
[cargo-make] INFO - Profile: development
[cargo-make] INFO - Running Task: legacy-migration
[cargo-make] INFO - Running Task: build-loader
error: want driver overlay2, got devicemapper
note: run with `RUST_BACKTRACE=1` for a backtrace
[cargo-make] ERROR - Error while executing command, exit code: 1
[cargo-make] WARN - Build Failed.
root@452f7025f91d:/usr/src/proot-rs# USE_CROSS=true CARGO_BUILD_TARGET=i686-unknown-linux-gnu cargo make build
[cargo-make] INFO - cargo make 0.35.0
[cargo-make] INFO - Build File: Makefile.toml
[cargo-make] INFO - Task: build
[cargo-make] INFO - Profile: development
[cargo-make] INFO - Running Task: legacy-migration
[cargo-make] INFO - Running Task: build-loader
error: want driver overlay2, got devicemapper
note: run with `RUST_BACKTRACE=1` for a backtrace
[cargo-make] ERROR - Error while executing command, exit code: 1
[cargo-make] WARN - Build Failed.
root@452f7025f91d:/usr/src/proot-rs# USE_CROSS=true CARGO_BUILD_TARGET=i686-linux-android cargo make build
[cargo-make] INFO - cargo make 0.35.0
[cargo-make] INFO - Build File: Makefile.toml
[cargo-make] INFO - Task: build
[cargo-make] INFO - Profile: development
[cargo-make] INFO - Running Task: legacy-migration
[cargo-make] INFO - Running Task: build-loader
error: want driver overlay2, got devicemapper
note: run with `RUST_BACKTRACE=1` for a backtrace
[cargo-make] ERROR - Error while executing command, exit code: 1
[cargo-make] WARN - Build Failed.
root@452f7025f91d:/usr/src/proot-rs# USE_CROSS=true CARGO_BUILD_TARGET=armv7-unknown-linux-musleabihf cargo make build
[cargo-make] INFO - cargo make 0.35.0
[cargo-make] INFO - Build File: Makefile.toml
[cargo-make] INFO - Task: build
[cargo-make] INFO - Profile: development
[cargo-make] INFO - Running Task: legacy-migration
[cargo-make] INFO - Running Task: build-loader
error: want driver overlay2, got devicemapper
note: run with `RUST_BACKTRACE=1` for a backtrace
[cargo-make] ERROR - Error while executing command, exit code: 1
[cargo-make] WARN - Build Failed.
root@452f7025f91d:/usr/src/proot-rs# USE_CROSS=true CARGO_BUILD_TARGET=armv7-unknown-linux-gnueabihf cargo make build
[cargo-make] INFO - cargo make 0.35.0
[cargo-make] INFO - Build File: Makefile.toml
[cargo-make] INFO - Task: build
[cargo-make] INFO - Profile: development
[cargo-make] INFO - Running Task: legacy-migration
[cargo-make] INFO - Running Task: build-loader
error: want driver overlay2, got devicemapper
note: run with `RUST_BACKTRACE=1` for a backtrace
[cargo-make] ERROR - Error while executing command, exit code: 1
[cargo-make] WARN - Build Failed.
root@452f7025f91d:/usr/src/proot-rs# USE_CROSS=true CARGO_BUILD_TARGET=arm-linux-androideabi cargo make build
[cargo-make] INFO - cargo make 0.35.0
[cargo-make] INFO - Build File: Makefile.toml
[cargo-make] INFO - Task: build
[cargo-make] INFO - Profile: development
[cargo-make] INFO - Running Task: legacy-migration
[cargo-make] INFO - Running Task: build-loader
error: want driver overlay2, got devicemapper
note: run with `RUST_BACKTRACE=1` for a backtrace
[cargo-make] ERROR - Error while executing command, exit code: 1
[cargo-make] WARN - Build Failed.
root@452f7025f91d:/usr/src/proot-rs# USE_CROSS=true CARGO_BUILD_TARGET=aarch64-unknown-linux-musl cargo make build
[cargo-make] INFO - cargo make 0.35.0
[cargo-make] INFO - Build File: Makefile.toml
[cargo-make] INFO - Task: build
[cargo-make] INFO - Profile: development
[cargo-make] INFO - Running Task: legacy-migration
[cargo-make] INFO - Running Task: build-loader
error: want driver overlay2, got devicemapper
note: run with `RUST_BACKTRACE=1` for a backtrace
[cargo-make] ERROR - Error while executing command, exit code: 1
[cargo-make] WARN - Build Failed.
root@452f7025f91d:/usr/src/proot-rs# USE_CROSS=true CARGO_BUILD_TARGET=aarch64-unknown-linux-gnu cargo make build
[cargo-make] INFO - cargo make 0.35.0
[cargo-make] INFO - Build File: Makefile.toml
[cargo-make] INFO - Task: build
[cargo-make] INFO - Profile: development
[cargo-make] INFO - Running Task: legacy-migration
[cargo-make] INFO - Running Task: build-loader
error: want driver overlay2, got devicemapper
note: run with `RUST_BACKTRACE=1` for a backtrace
[cargo-make] ERROR - Error while executing command, exit code: 1
[cargo-make] WARN - Build Failed.
root@452f7025f91d:/usr/src/proot-rs# USE_CROSS=true CARGO_BUILD_TARGET=aarch64-linux-android cargo make build
[cargo-make] INFO - cargo make 0.35.0
[cargo-make] INFO - Build File: Makefile.toml
[cargo-make] INFO - Task: build
[cargo-make] INFO - Profile: development
[cargo-make] INFO - Running Task: legacy-migration
[cargo-make] INFO - Running Task: build-loader
error: want driver overlay2, got devicemapper
note: run with `RUST_BACKTRACE=1` for a backtrace
[cargo-make] ERROR - Error while executing command, exit code: 1
[cargo-make] WARN - Build Failed.
root@452f7025f91d:/usr/src/proot-rs#
root@452f7025f91d:/usr/src/proot-rs# RUST_BACKTRACE=1 USE_CROSS=true CARGO_BUILD_TARGET=aarch64-linux-android cargo make build
[cargo-make] INFO - cargo make 0.35.0
[cargo-make] INFO - Build File: Makefile.toml
[cargo-make] INFO - Task: build
[cargo-make] INFO - Profile: development
[cargo-make] INFO - Running Task: legacy-migration
[cargo-make] INFO - Running Task: build-loader
error: want driver overlay2, got devicemapper
note: run with `RUST_BACKTRACE=1` for a backtrace
[cargo-make] ERROR - Error while executing command, exit code: 1
[cargo-make] WARN - Build Failed.
root@452f7025f91d:/usr/src/proot-rs#
Originally posted by @oxr463 in #55 (comment)
docker run -it rust:alpine /bin/sh
According to the unshare(2) man page:
A call to unshare(CLONE_FS) will:
CLONE_FS
Reverse the effect of the clone(2) CLONE_FS flag. Unshare
filesystem attributes, so that the calling process no
longer shares its root directory (chroot(2)), current
directory (chdir(2)), or umask (umask(2)) attributes with
any other process.
There is no handling of unshare() by proot-rs yet, so I have documented it here.
The current loader is written in c. It was extracted and modified from the original PRoot implementation.
If the guest location is a symbolic link, it is dereferenced to ensure the new content is accessible through all the symbolic links that point to the overlaid content. In most cases this default behavior shouldn't be a problem, although it is possible to explicitly not dereference the guest location by appending it the ! character: -b host_path:guest_location!.
We still can’t run cargo test
correctly, it always times out.
see: https://github.com/proot-me/proot-rs/runs/2177032707?check_suite_focus=true
It also times out on my computer running Manjaro distribution with Linux kernel version 5.11.2.
String
only works on valid UTF-8 :(
Reference(s):
There are two kinds of documentation required:
Reference(s):
curl -LO https://github.com/proot-me/proot-rs/releases/download/v0.1.0/proot-rs-v0.1.0-aarch64-linux-android.tar.gz
tar -xf proot-rs-v0.1.0-aarch64-linux-android.tar.gz
curl -LO https://us.images.linuxcontainers.org/images/debian/sid/arm64/default/20210821_05:28/rootfs.tar.xz
mkdir debian
cd debian
tar -xf ../rootfs.tar.xz
cd ..
./proot-rs -r debian /bin/sh
echo $?
159
Usage
Not usable for now (work in progress).
Do we have a unit test for this?
/// Working directory in guestfs, e.g., `/proc/self/cwd`, is always absolute
Originally posted by @oxr463 in #25 (comment)
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.