Skip to main content

The OCCAM saga

Project description

PyPI version Build Status

Description

OCCAM is a whole-program partial evaluator for LLVM bitcode that aims at debloating programs and shared/static libraries running in a specific deployment context.

OCCAM architecture

OCCAM architecture

Docker

A pre-built and installed version of OCCAM can be obtained using Docker:

docker pull sricsl/occam:bionic
docker run -v `pwd`:/host -it sricsl/occam:bionic

Alternatively, it can be built and installed from source as follows.

Prerequisites

OCCAM currently works on Linux, macOS, and FreeBSD. It depends on an installation of LLVM. OCCAM currently is built on the top of llvm-10.0 which requires a C++ compiler supporting c++14. You will also need the Google protocol buffer compiler protoc and the corresponding Python package. Some OCCAM components (such as sea-dsa and crab require the boost library >= 1.65.

If you need to generate application bitcode (that OCCAM operates on), you will want to install WLLVM, either from the the pip package or the GitHub repository.

The test harness also requires lit and FileCheck. FileCheck can often be found in the binary directory of your LLVM installation. However, if you built your own, you may need to read this. Hint: the build produces it, but does not install it. (Try locate FileCheck, then copy it to the bin directory.)

Detailed configuration instructions for Ubuntu 18.04 can be gleaned from bootstrap.sh as well as the Travis CI scripts for each branch .travis.yml.

Building and Installing

Set where OCCAM's library will be stored:

  export OCCAM_HOME={path to location in your home directory}

Point to your LLVM's location, if non-standard:

  export LLVM_HOME=/usr/local/llvm-10.0
  export LLVM_CONFIG=llvm-config-10.0

Set where system libraries, including Google Protocol Buffers, are located:

  export LD_FLAGS='-L/usr/local/lib'

Clone, build, and install OCCAM with:

  git clone --recurse-submodules https://github.com/SRI-CSL/OCCAM.git
  make
  make install
  make test

Using OCCAM

You can choose to record logs from OCCAM by setting the following variables:

  export OCCAM_LOGFILE={absolute path to log location}
  export OCCAM_LOGLEVEL={INFO, WARNING, or ERROR}

Using razor

razor is a pip package that relies on the same dynamic library as occam. So you should first build and install occam as described above. razor provides the commandline tool slash for end users. You can either install razor from this repository, or you can use:

pip install razor

To install an editable version from this repository:

make -f Makefile develop

This may require sudo privileges. Either way you can now use slash:

slash [--work-dir=<dir>]  [--force] [--no-strip] [--intra-spec-policy=<type>] [--inter-spec-policy=<type>] [--use-pointer-analysis] [--enable-config-prime] <manifest>

where

type=none|aggressive|nonrec-aggressive|bounded|onlyonce

The value none will prevent any inter or intra-module specialization. The value aggressive specializes a call if any parameter is a constant. The value nonrec-aggressive specializes a call if the function is non-recursive and any parameter is a constant. The value bounded makes at most k copies where k can be chosen by option --max-bounded-spec. The value onlyonce makes a copy of a function only if the function is called exactly once.

To function correctly slash calls LLVM tools such as opt and clang++. These should be available in your PATH, and be the currently supported version (10.0). Like wllvm, slash, will pay attention to the environment variables LLVM_OPT_NAME and LLVM_CXX_NAME if your version of these tools is adorned with suffixes.

The Manifest

The manifest for slash should be valid JSON. The following keys have meaning:

  • main : a path to the bitcode module containing the main entry point.

  • modules: a list of paths to the other bitcode modules needed.

  • binary : the name of the desired executable.

  • native_libs : a list of flags (-lm, -lc, -lpthread) or paths to native objects (.o, .a, .so, .dylib)

  • ldflags: a list of linker flags such as --static, --nostdlib

  • name: the program name

  • static_args : the list of static arguments you wish to specialize in the main() of main.

  • dynamic_args : a number that indicates the arguments the specialized program will receive at runtime. If this key is omitted then the default value is 0 which means that the specialized program does not expect any parameter.

  • lib_spec: list of library bitcode you wish to specialize with respect to main or a list of main functions given by main_spec.

  • main_spec: list of bitcode modules each containing a main function used by lib_spec.

As an example, (see examples/linux/apache), to previrtualize apache:

{ "main" : "httpd.bc"
, "binary" : "httpd_slashed"
, "modules" : ["libapr-1.so.bc", "libaprutil-1.so.bc", "libpcre.so.bc"]
, "native_libs" : ["-lcrypt", "-ldl", "-lpthread"]
, "name"    : "httpd"
, "static_args" : ["-d", "/var/www"]
}

Another example, (see examples/linux/musl_nweb), specializes nweb with musl libc.c:

{ "main" :  "nweb.o.bc"
, "binary" : "nweb_razor"
, "modules" : ["libc.a.bc"]
, "native_libs" : ["crt1.o", "libc.a"]
, "ldflags" : ["-static", "-nostdlib"]
, "name" : "nweb"
, "static_args" : ["8181", "./root"]
, "dynamic_args" : "0"
}

A third example, (see examples/linux/tree), illustrates the use of the dynamic_args field to partially specialize the arguments to the tree utility.

{ "main" : "tree.bc"
, "binary"  : "tree"
, "modules"    : []
, "native_libs" : []
, "ldflags" : [ "-O2" ]
, "name"    : "tree"
, "static_args" : ["-J", "-h"]
, "dynamic_args" : "1"
}

The specialized program will output its results in JSON notation (-J) that will include a human readable size field (-h). The specialized program expects one extra argument, either a directory or another flag to output the contents of the current working directory.


This material is based upon work supported by the National Science Foundation under Grant ACI-1440800. Any opinions, findings, and conclusions or recommendations expressed in this material are those of the author(s) and do not necessarily reflect the views of the National Science Foundation.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

razor-1.1.2.tar.gz (35.4 kB view details)

Uploaded Source

Built Distribution

razor-1.1.2-py3-none-any.whl (40.9 kB view details)

Uploaded Python 3

File details

Details for the file razor-1.1.2.tar.gz.

File metadata

  • Download URL: razor-1.1.2.tar.gz
  • Upload date:
  • Size: 35.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.3.0 pkginfo/1.7.0 requests/2.25.1 setuptools/53.0.0 requests-toolbelt/0.9.1 tqdm/4.59.0 CPython/3.9.2

File hashes

Hashes for razor-1.1.2.tar.gz
Algorithm Hash digest
SHA256 7dd771163c455c7ce7567e00172a994ef5c90e325893ab195a468a02078836d3
MD5 252c409a0be459d4095b429e11b6cd71
BLAKE2b-256 64f0586e6633340e1721cb82b9b0895fc4191e8a49ae2d44258e07956c14bc8e

See more details on using hashes here.

File details

Details for the file razor-1.1.2-py3-none-any.whl.

File metadata

  • Download URL: razor-1.1.2-py3-none-any.whl
  • Upload date:
  • Size: 40.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.3.0 pkginfo/1.7.0 requests/2.25.1 setuptools/53.0.0 requests-toolbelt/0.9.1 tqdm/4.59.0 CPython/3.9.2

File hashes

Hashes for razor-1.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 78e46e622c25053f1280323f0841b7145b4c40cb247cbb2e09458b795f784ca3
MD5 ed6615ba191d6902e1f4db1e5d6a69d0
BLAKE2b-256 65c7c290aff6a52054eedb1bf61916304258665314242a5b613eb41ce30e020f

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page