# Quickstart

1. install platform-extension-proxy-config package (it pulls in platform-extension-proxy)
2. reboot the system

The policy is now checked but it's not enforced as permissive mode is on by default (see description the end)

Next steps should be:
- check /run/pe-proxy-deny.log and update /etc/platform-extension/proxy/policy accordingly
- disable the permissive mode:

    echo > /etc/platform-extension/proxy/permissive

# Doc
A preloaded library that checks file system access against a policy.

The platform-extension-proxy package installs
/usr/lib64/libplatform-extension-proxy.so.0.0.0. The library does nothing
until a configuration is installed. The default configuration is the
platform-extension-proxy-config package. It installs /etc/ld.so.preload,
which loads the library into every process, and the policy, enforce and
permissive files described below. The library provides proxy functions for various libc functions
accesing files and directories and checks if a process, based on policy,
can access requsted files. The main purpose of this library is to check
if hal services don't access files beyond permitted scope.

This library is a development tool and should not be used on a production image.

The access policy is loaded from /etc/platform-extension/proxy/policy at
startup. Each rule has a subject path, a target path, and an allow or deny
verdict. First matching rule wins, default is allow. The pattern matching works
like this:
- /dir matches /dir, /dir/file but not /directory,
- /dir/ does not match /dir itself, it only matches /dir/file,
- a trailing * matches any path starting with the part before it, e.g.
  /usr/lib/libfoo.so* matches /usr/lib/libfoo.so.1.2.3 (and /usr/lib/libfoo.so.bak),
  * anywhere else in the path is not special,
- as a special case / matches everything.
# comments are allowed but only on the line start. If the policy is malformed
or fails to load, nothing is blocked.

The subject of a rule is the canonical path of the object (executable or
shared library) that called the libc function. If a HAL module accesses a
file through another library (for example glib or libstdc++), the subject is
that library, not the HAL module. The target is the canonical path of the
accessed file. For calls that do not follow a symbolic link in the last path
component (for example lstat, unlink, rename or O_NOFOLLOW), only the parent
directory is resolved. Only a policy verdict denies an access. If the proxy cannot resolve the caller
or the path (an internal error), the call is let through and the error is
logged. Denied accesses fail with EACCES and are logged to
/run/pe-proxy-deny.log (/dev/kmsg for PID 1). The log is mode 0666 and
labelled "*" so that every process can append to it; tmpfiles.d sets this up
at boot and the library does the same if it creates the file earlier.

The library cannot see accesses that do not go through the dynamically
linked libc functions it replaces. These include statically linked binaries,
direct syscall(2) calls, io_uring, and file access inside libc itself (for
example NSS or the dynamic loader).

Additionally, /etc/platform-extension/proxy/enforce is loaded at startup. Each
line contains a name of a function. If a function is mentioned in this file,
all checks for this function are enabled. Again, # comments are allowed but
only on the line start. A name this version of the library does not know is
logged and ignored. A malformed file or one that fails to load is treated as
if empty. A missing policy or enforce file is silently treated as empty.

Performance notes:
The calling object of each proxied call is determined with _dl_find_object()
and cached per loaded object, so calls from objects that no deny rule applies
to cost nothing extra. For the others, the directory part of the target path
is resolved once and cached (32 entries, about 8 KB, in processes that
perform checks only), then the last component is checked with one lstat(2).
The cache is flushed whenever the process itself renames, unlinks, symlinks,
mounts etc., and entries expire after HAL_DIRCACHE_TTL_MS (default 1000), so
a change made to the file system by another process, e.g. retargeting a
symlink in a directory path, can go unnoticed for up to that long. Build with
-DHAL_DIRCACHE_TTL_MS=0 to disable the directory cache.
bench/run.sh, bench/difftest.sh and bench/cachetest.sh measure and test all
of this.

Permissive mode:
This mode enables logging acccess violations without actually denying access
to files. The mode can be enabled by creating non-zero sized file named
/etc/platform-extension/proxy/permissive or setting the action field
of a particular rule to "log".

Providing another configuration:
The configuration is the only interface to the library, there is no other
dependency between the two packages. A package replacing
platform-extension-proxy-config should
- have "Requires: platform-extension-proxy" (the library does not require config),
- install /etc/ld.so.preload naming the soname
  /usr/lib64/libplatform-extension-proxy.so.0 (not the full version),
- install policy, enforce and permissive in /etc/platform-extension/proxy/.
