Giter Site home page Giter Site logo

proot-me / proot-rs Goto Github PK

View Code? Open in Web Editor NEW
119.0 9.0 20.0 512 KB

Rust implementation of PRoot, a ptrace-based sandbox

License: GNU General Public License v3.0

Rust 92.43% C 1.47% Shell 5.54% Dockerfile 0.56%
rust sandbox ptrace seccomp non-root linux bindings bind mount container

proot-rs's People

Contributors

imlk0 avatar jyn514 avatar oxr463 avatar scott-hamilton avatar vincenthage avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

proot-rs's Issues

Docker

docker run -it rust:alpine /bin/sh

Failed to execute statically linked binaries

A minimal test case:

echo 'int main(){return 0;}' | gcc -static -o rootfs/bin/test_static_linked -x c -
./target/debug/proot-rs --rootfs=./rootfs -- /bin/test_static_linked

output:

image

Cannot run Debian in Termux

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

Processing the result of getdents64()

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

Integration tests

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.

Document default cwd

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)

Get /bin/sleep to run and exit correctly

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:

  • parse the command to be executed from the cli
  • implement kernel::execve::exit::translate() so that execve() can return correctly
  • solve some issues in the path translation functions

A call to unshare(CLONE_FS) from tracee may break the emulation of cwd.

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.

Add support for Android platform and other architectures (e.g. arm, aarch64)

The current implementation is written for Linux x86_64 and lacks support for android and arm/aarch64.

These issues need to be resolved:

  • Language support: rust has great support for the android platform
  • Third-party libraries: some libraries lack support for the android platform (e.g.sc), some libraries behave differently on the arm/aarch64 architecture (e.g. missing libc::user_regs_struct)
  • Our code: need to write some extra code for arm/aarch64 (mainly the syscall and registers part).

Document behavior when updating a tracee's cwd

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.

  1. 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.
  2. 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.

Rewrite loader in rust

The current loader is written in c. It was extracted and modified from the original PRoot implementation.

Remaining steps for first working version (x86-64)

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):

Registers modification (src/register)

  • push regs
  • set_sysarg_path

Path translations (src/filesystem)

  • symlinks translation
  • bindings initialisation
  • exe initialisation

Execve (src/kernel/execve)

  • loader
  • shebang
  • enter
  • exit

Standard syscalls (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.

  • chdir
  • chmod_access_mknod_at
  • dir_link_attr
  • getcwd
  • inotify_add_watch
  • link_at
  • link_rename
  • mount
  • open
  • open_at
  • pivot_root
  • readlink_at
  • rename_at
  • standard_syscall
  • stat_at
  • sym_link
  • sym_link_at
  • uname
  • unlink_mkdir_at

CLI (src/cli)

  • exe

General

  • tracees termination in case of tracer panicking.

Trailing slash is removed by proot-rs

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:

image
in hostfs:

image

This issue and #40 are both related to handling trailing slash

compilation fails on riscv64

I mean I would edit loader-shim/src/main.rs if I knew what was going on there but it uses handwritten assembly.

docker-compose error: want driver overlay2, got devicemapper

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)

`cargo build --release` doesn't compile

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

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.