atlas-brown/sash: Ahead-of-time analysis of shell program effects. Contribute to atlas-brown/sash development by creat

github.com · 2026-10-01 · by Long Nguyen ·github
Ahead-of-time analysis of shell program effects. Contribute to atlas-brown/sash development by creating an account on GitHub.

atlas-brown/sash

Ahead-of-time analysis of shell program effects. Contribute to atlas-brown/sash development by creating an account on GitHub.

11 stars · 3 forks

README

SaSh: Ahead-of-time Analysis of Shell Program Effects

Quick jump: Installation | Examples | Contributing | Citation | Contact SaSh is a static analysis tool for the Unix shell, using symbolic execution to find bugs in shell programs. It currently supports the set of features and syntax defined by the POSIX standard. News: SaSh received a best paper award at SOSP'26!

Installation SaSh can be installed natively on Linux and MacOS, or used through Docker. All dependencies of SaSh are listed in the Dockerfile and pyproject.toml. The following installation instructions make use of these configurations as appropriate. Manual Make sure you have the following installed:

git make automake autoconf libtool g++-13 or clang-17 (or newer) uv (recommended) or pipx

You already have g++-13 or clang-17 if you are on Debian 13, Ubuntu 23, or newer. On MacOS, clang-17 is part of the xcode command line tools. Then, run: CFLAGS="-std=gnu17" uv tool install git+https://github.com/atlas-brown/sash.git uv tool update-shell # If PATH needs to be updated Or: CFLAGS="-std=gnu17" pipx install git+https://github.com/atlas-brown/sash.git pipx ensurepath # If PATH needs to be updated MacOS (using brew) brew tap atlas-brown/tap brew trust atlas-brown/tap brew install asash Requires Docker. Nix / NixOS nix profile add github:atlas-brown/sash Docker If you want to avoid installing these dependencies, you can use SaSh through Docker. To install: git clone https://github.com/atlas-brown/sash.git cd ./sash docker build -t sash . docker run --rm sash --help # Should output a help message

Install the wrapper script (see below) onto your PATH, then clean up:

mkdir -p ~/.local/bin install -m 0755 ./scripts/asash-docker.sh ~/.local/bin/asash cd .. rm -rf ./sash ImportantThe sash image reads files from the host, so the file to be analyzed must be mounted into the container. The asash-docker.sh wrapper installed above handles this for you: it mounts each file argument (read-only) into the container at its own absolute path and passes everything else through to SaSh, so you can just run asash file.sh from anywhere. It runs under either Docker or Podman, auto-detecting whichever is installed (override with ASASH_RUNTIME).

To pass extra `docker run` flags (e.g. '--privileged' for pausing/resuming

execution via CRIU), set ASASH_DOCKER_ARGS:

ASASH_DOCKER_ARGS=--privileged asash file.sh

To run a differently-tagged image, set ASASH_IMAGE (default: sash).

Without the wrapper, you can mount manually, but then SaSh can only see files

under the mounted directory:

docker run --rm -v "$(pwd)":/ws -w /ws sash file.sh

Examples Empty variable leading to deletion of critical paths Consider a script that captures the output of a command and later uses that value to clean up a directory: #!/bin/sh ROOT="$(cd ${0%/*} && echo $PWD)" rm -rf "$ROOT/"* If the cd fails, $ROOT becomes empty. Then, "$ROOT/" expand to /, making rm -rf delete every user-writable file on the system. SaSh detects this ahead of time: $ asash install.sh

Line 3 (error): Word splitting or empty variable could lead to deletion of system file /*

A similar bug was responsible for the 2015 Steam updater incident1. Possible data loss from moving files This script moves two files to the same destination: #!/bin/sh mv a target mv b target If target is a directory, both files end up inside it and the operation is safe. If target is a regular file, the first mv renames a to target, and the second mv renames b to target, silently overwriting a. SaSh warns about the risk: $ asash organize.sh

Line 3 (error): Command 'mv' deletes the following paths, one of which has not been read, potentially causing loss of data: target
but only if unknown paths are assumed to be files

Contributing The project provides a configuration file for containerized development. Additionally, the Dockerfile provides an additional target for development (dev), which does not copy the project files into the container, to allow for mounting. docker build --target dev -t sash-dev . docker run --rm -it -v "$(pwd)":/app -v /app/.venv sash-dev

Again, remember to add '--privileged' if you need to use CRIU

Testing This project uses pytest. To run all tests, use uv run pytest. To ensure correct test discovery when writing new tests:

Test files should be named with the prefix test_ (e.g., test_example.py). Test functions should also start with test_ (e.g., def test_example(): ...).

Citation If you use SaSh in your research, please cite the paper: @inproceedings{sash:sosp:2026, title = {Ahead-of-time Analysis of Shell Program Effects}, author = {Lazarek, Lukas and Lamprou, Evangelos and Kapetanakis, George and Zhao, Eric and Zheng, Zhiwen and Greenberg, Michael and Kallas, Konstantinos and Vasilakis, Nikos}, year = {2026}, month = {sep}, booktitle = {Proceedings of the 32nd ACM Symposium on Operating Systems Principles}, location = {Prague, Czechia}, publisher = {Association for Computing Machinery}, address = {New York, NY, USA}, series = {SOSP '26}, url = {https://sigops.org/s/conferences/sosp/2026/}, keywords = {Unix, Linux, shell, static analysis, effects}, artifact = {https://github.com/atlas-brown/sash}, } Contact For questions please contact atlas@brown.edu, or open an issue on GitHub. Footnotes

https://github.com/ValveSoftware/steam-for-linux/issues/3671 ↩

source

github.com · 2 images · 113 links

Comments (0)

No comments yet