{"id":16923214,"url":"https://github.com/mathetake/tvisor","last_synced_at":"2025-03-23T17:30:56.925Z","repository":{"id":233095052,"uuid":"785994021","full_name":"mathetake/tvisor","owner":"mathetake","description":"tvisor is a tiny 100% userspace syscall interception framework ","archived":false,"fork":false,"pushed_at":"2024-04-13T22:59:29.000Z","size":21138,"stargazers_count":43,"open_issues_count":0,"forks_count":2,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-03-15T07:14:27.466Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mathetake.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2024-04-13T05:27:18.000Z","updated_at":"2025-01-15T18:03:55.000Z","dependencies_parsed_at":"2024-04-13T21:04:29.923Z","dependency_job_id":null,"html_url":"https://github.com/mathetake/tvisor","commit_stats":null,"previous_names":["mathetake/tvisor"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mathetake%2Ftvisor","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mathetake%2Ftvisor/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mathetake%2Ftvisor/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mathetake%2Ftvisor/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mathetake","download_url":"https://codeload.github.com/mathetake/tvisor/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245140778,"owners_count":20567447,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-13T19:58:16.268Z","updated_at":"2025-03-23T17:30:51.873Z","avatar_url":"https://github.com/mathetake.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# tvisor: a Tiny Thread-level syscall interception framework\n\n\u003e [!WARNING]\n\u003e I stopped working on this project because I realized that almost the same thing can be achieved\n\u003e with [Kernel runtime security instrumentation](https://lwn.net/Articles/798157/) very easily, though it is _not_\n\u003e userspace mechanism.\n\u003e Therefore, the sole purpose of this repository is to show how to build an *userspace* syscall interception framework\n\u003e by only relying on the (classic) seccomp-bpf.\n\u003e\n\u003e The code is not complete at all but at least 95% of basic musl-libc tests are passing for \"no-op\" syscall\n\u003e interception.\n\u003e The one\n\u003e of the most\n\u003e difficult parts that I have not implemented is proper signal handling of blocked signals while executing\n*interruptible* syscalls.\n\u003e\n\u003e I am not sure if I will continue this project, but I will keep this repository as a reference for the future.\n\n\ntvisor is a tiny _100% userspace_ syscall interception _framework_ that can be used to build a program to monitor\nsyscalls.\n\"T\" indicates both \"Tiny\" and \"Thread-level\". Only available on Linux.\n\nA program built with tvisor will be a single-binary, and it does not spawn guest in a separate process, but it directly\nruns the guest in\nthe same process.\nIt runs in a higher address space than the guest, and injects a tiny monitor in the process, then starts running the\nguest\nin the same process. The monitor is responsible for intercepting the syscall and forwarding it to the host while\nrejecting/modifying\nthe syscall arguments if necessary.\nIt spawns a \"kernel\" thread which corresponds to each guest program thread. A kernel is responsible for handling\nsyscalls\nin the corresponding guest thread.\n\ntvisor is able to run **any binary** either statically or dynamically(TODO but should be possible) linked, without any\nmodification (with some exceptions).\n\n## How it works\n\nFirst of all, the tvisor binaries are running in a higher address space than the guest by passing `--image-base` linker\nflag when building the tvisor binary. Tvisor users run the guest binary\nas `./tvisor \u003ctvisor_args\u003e -- \u003cguest_binary\u003e \u003cguest_args\u003e`. Tvisor binary does the following things:\n\n1. Parse the ELF binary and load it into the same virtual memory space.\n2. Installs special signal handlers to handle *all* signals.\n3. Spawns the \"kernel thread\" corresponding to each guest thread. Each kernel thread is responsible\n   for handling _target_ syscalls in the corresponding guest thread. It spawns the corresponding guest thread and starts\n   running\n   the guest thread.\n4. Each guest thread installs sigaltstack to handle any signals raised in the guest thread. The sigalt stack contains\n   the various data structures that allow each signal handler can communicate with the corresponding kernel thread.\n5. Each guest thread also\n   installs [`seccomp-bpf`](https://www.kernel.org/doc/html/v4.19/userspace-api/seccomp_filter.html) filter to intercept\n   syscalls, which\n   raises `SIGSYS` signals. Which syscall is intercepted is determined by users of tvisor library.\n6. After all the setup is done, the guest thread start running the guest executable code.\n\n## Example\n\nThere are two tvisor usage example programs in [tvisor/bin](./tvisor/bin). To build them,\nrun `make build`. You see the binary `./tvisor/target/aarch64-unknown-none/release/tvisor-fs` which is a freestanding\nlinux ELF binary.\n\ntvisor-fs example program is a simple program that modifies the current working directory and root directory of the\nguest program by intercepting getcwd and open kind system calls. For example, for the example program that prints the\ncurrent working directory `getcwd`,\ntvisor-fs runs as a file system sandbox program that changes the current working directory to `/tmp`:\n\n```\n$ ./getcwd\nCurrent working directory: /Users/mathetake/tvisor\n$ tvisor-fs --cwd /anydir -- ./getcwd\nCurrent working directory: /anydir\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmathetake%2Ftvisor","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmathetake%2Ftvisor","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmathetake%2Ftvisor/lists"}