pito system call interceptor system

Pito is a set of c++0x header libraries for writing system call interceptor shared libraries based on LD_PRELOAD wrappers. Pito also provides the program “pito” for loading programs with such wrappers. “pito” is capable of passing command line arguments to loaded libraries.

1: Using pito and loading plugins

% pito log touch cock
2041: calling open(cock, 2369, 438) - 3

% pito -h
pito 0.9.9
usage: pito [arguments] <wrapper library name> [wrapper arguments] <program> [program arguments]
 -v [ --verbose ]       increase verbosity
 -h [ --help ]          display help
 -s [ --silent ]        remain silent
 -l [ --library-dir ]   pito library directory

% pito -v log ls hello
load interceptor library (/usr/lib/libpito_log.so)
2112: calling opendir(hello) - 0x24a1d30
2112: calling readdir(0x24a1d30) - 0x24a1d58
2112: calling readdir(0x24a1d30) - 0x24a1d70
2112: calling readdir(0x24a1d30) - 0x24a1d88
2112: calling readdir(0x24a1d30) - 0x24a1da0
2112: calling readdir(0x24a1d30) - 0
baby  kitten

% pito sandbox -h
pito sandbox arguments
 -b [ --blacklist ]   disallow writes to this directory
 -w [ --whitelist ]   allow writes to this directory
 -p [ --pretend ]     pretend to allow writes to this directory
 -v [ --verbose ]     increase verbosity
 -h [ --help ]        display help

% pito sandbox -b/ touch cock
open: /tmp/cock denied
utimensat: /tmp/cock denied
touch: cannot touch 'cock': Permission denied

% pito sandbox -w blah -v touch cock
default: P
white list: /tmp/blah
open: /tmp/cock pretend

The log plugin

plugin/log/helper.hpp - print system calls names, arguments and return values.

#ifndef PITO_LOG_HELPER_HPP
#define PITO_LOG_HELPER_HPP

#include <pito/system_call.hpp>
#include <pito/lib/traits.hpp>

#include <chilon/print.hpp>

#include <iostream>

namespace pito { namespace log {

#ifdef PITO_LOG_PID
struct context {
    context() {
       pid_ = getpid();
    }
    pid_t   pid_;
};

// Object created in source file, ensures context constructor gets run
// as library is opened.
context ctxt;
#endif

// This is the system call handler, certain tags can be handled
// specially using template parameter specialisation on the tag
template <class Tag>
struct system_call : system_call_real<Tag> {

    template <class... Args>
    PITO_RETURN(Tag) operator()(Args... args) {
        chilon::print(std::cerr, chilon::color::blue);
#ifdef PITO_LOG_PID
        chilon::print(std::cerr, ctxt.pid_, ": ");
#endif
        // name() inherited from system_call_real, contains name of
        // system call as cstring. this-> is necessary due to call
        // through template base.
        chilon::print(std::cerr, "calling ", this->name(), "(");
        chilon::print_join(std::cerr, ", ", args...);
        std::cerr << ") - " << std::flush;

        // Call the real system call.
        auto ret = this->system(args...);
        chilon::println(std::cerr, ret, chilon::color::neutral);
        return ret;
    }
};

} }

#endif

plugin/log/libc.cpp - redirect system calls to helper.cpp objects

// This define is used by pito/jail/c.hpp and pito/lib/c.hpp to work
// out where to direct system calls. In this case the system calls
// go through the template class pito::log::system_call.
#define PITO_SYSTEM_CALL_BASE  log::system_call
#define PITO_LOG_PID
#include <pito/plugin/log/helper.hpp>
#include <pito/jail/c.hpp>
#include <pito/lib/c.hpp>

Writing plugins

Until this website is updated to include documentation for writing plugins the best way to start is to copy one of the existing plugins from git out of src/pito/plugins. This plugin can be added to the build process of pito by adding its directory name as for the existing plugins in src/pito/plugins/CMakeLists.txt. The log plugin is the simplest to copy and the sandbox plugin shows how plugins may receive and use command line arguments.

Protected environment variables

Any environment variables beginning with “PITO_&rdquo (in addition to the LD_PRELOAD environment variable) will be protected by the underlying library code and passed on in the environment unmodified to all instances of a library. These variables can be used in a plugin's init function to pass options set by command line arguments.

Supported operating systems

pito is primarily developed and tested on Linux. It has also been developed and tested on OS X. It may also work on other unix environments, any help testing and/or porting pito to other operating systems would be greatly appreciated.

Supported development environments

pito uses C++0x features already available in certain compilers. It is primarily developed using gcc 4.5 and has also been tested using gcc 4.4.

Pito packages