** Libpulp

Table of contents:
1 - Introduction
2 - Consistency
3 - The patching process
4 - Project structure and tools
5 - Description file syntax

-------------------------------------------------------------------------------
* 1 * Introduction

Libpulp is a library (and a framework) that enables live patching of other user
space libraries. Most of its tools rely on ptrace to attach and modify functions
in libraries which are used by running applications. To be suitable for live
patching, these target libraries are required to be compiled through a modified
toolchain, which is also provided within the Libpulp package.

Libpulp is available under GPLv3, at https://github.com/suse/libpulp

-------------------------------------------------------------------------------
* 2 * Consistency

To ensure correct program semantics, it is important to keep atomicity while
applying a live patch. This means that, after the moment of patching, all the
functions which are part of the live patch set are migrated into their newer
versions simultaneously, never again being executed in their older versions.

To achieve atomicity while applying a patch, it is important to verify a
property named consistency. Briefly, before modifying an application's function
during runtime, it is necessary to ensure that the function is not currently
active -- it is not being executed, nor will be returned to from a function
currently active. This way, if a function A calls a function B, and the program
is stopped during the execution of B for patching, neither A nor B can be
patched.

To enable consistency verification, Libpulp uses special instrumentation of
the library's entry points in a way that the library itself flags whenever
control-flow enters or leaves its scope. From that, it is possible to assume
that if the library was not entered, none of the functions belonging to the
library is currently executing and, thus, all of them can be patched.

-------------------------------------------------------------------------------
* 3 * The patching process

A live patch is built on top of existing libraries. The Libpulp framework
provides the tools to create the patches. Once the patch is created, it is
applied through a ptrace-based tool, that will attach to the target process,
check if it is compliant with live patching, verify that the target library
is properly loaded into its address space, verify the process' consistency as
mentioned above and then, through control-flow redirection, use routines from
Libpulp to make the process load the new version of the functions to its
address space and then, through adding detours to the old function prologues,
ensure that only the new version of the functions are invoked.

The detours are not patched directly on top of previously existing instructions.
Instead, the function must be emitted by gcc with an area of padding nops which
is then overwritten. This is important to enable per-thread migration of
universes -- by having a thread-local variable which flags if a given thread
was already migrated into a new universe or not, it is possible to decide,
upon function invocation, if the newer or older version of the function must
be reached by the control-flow. In this scenario, in the moment of the patch
application, a thread which has functions from the target library in an active
state won't be migrated, and the older version will continue to be reached.
Through using the instrumentation in the function entry points, this thread
can later migrate itself safely (given that an entering library is always
consistent).

-------------------------------------------------------------------------------
* 4 * Project structure and tools

-- lib

Contains the Libpulp library (which has the routines used by the live patching
procedures).

The library objects are:
- trm.S: This is an object that must be linked into libraries which will later
be live patching-enabled. It contains the routines used to track the library's
entry points and routines used to later verify the consistency of given threads.
- libpulp.c: This object will later be compiled into the libpulp.so, which can
be preloaded by any process. It contains the routines which will later be
redirected to through ptrace and will make the actual patching happen.

-- tools

Contains the tools used to trigger, check and build live patches.

The tools are:
- dynsym_gate: This tool is used to modify the library entry points to the
special instrumentation used by Libpulp to track consistency. It modifies the
values of the targets in the dynamic symbol table to, instead of pointing to
the regular function, point to a trampoline table emitted by ld.

- packer: This tool creates the live patch metadata out of a description file
and from the targeted library. The description file syntax is described below.

- trigger: This tool is used to introspect into the to-be-patched process and
trig the live patching process. The 'trigger' directory also holds the tool
check, which introspects into the process and verifies if a given patch was
applied.

- dump: This tool parses and dumps the contents of a live patch metadata file.

- dispatcher: This tool retrieves the to-be-patched library from the live patch
metadata file and verifies all the running process which have the target library
loaded. If the argument "patch" is supplied, it invokes the trigger tool for
every process in the list. If the argument "check" is supplied, it only verifies
if the given process was previously patched.

-- examples

Contains example libraries, applications and live patches, used to test and
verify that Libpulp works properly.

-------------------------------------------------------------------------------
* 5 * Description file syntax

The live patching metadata is built from a description file which should be
written with the following syntax:

1: <absolute path of .so with patching functions>
2: @<absolute path of the first targeted library>
3: <old_fname_1>:<new_fname_1>
4: <old_fname_2>:<new_fname_2>
5: @<absolute path to the second targeted library>
6: <old_fname_1>:<new_fname_1>
7: ...

Line 1 brings the absolute path of a .so file that contains all the functions
which will be used to replace functions in the running process. Line 2 brings
the absolute path for a library which will be patched. These lines, which
bring target libraries, are preceded with an '@'. The following lines, 3 and 4,
bring pairs of replaced and replacing functions which belong to the object
previously declared (in this case, the object in line 2). Line 5 brings a second
to-be-patched object. Line 6 brings a replacement pair of functions respective
to the object mentioned in line 5.
