
Status
This project is under Development, most functionalities are not implemented yet.
Presentation
LDFL (LD File Liar) is a powerful LD_PRELOAD
library that intercepts and modify libc
file system operations. It allows you to:
- Log Filesystem Interactions: File & Directory manipulation can be logged to syslog or stderr
- Remap File Paths: Redirect file access to different locations
- Control File Access: Restrict or allow access to specific files/directories
- Modify File Permissions: Change ownership and permissions on-the-fly
- Memory-based Files: Serve files directly from memory
- Static Content: Serve predefined static content
- Executable Redirection: Redirect executable paths
This tool can be used on existing binaries or can be included with a static configuration header inside your projects.
Documentation
You can also view the latest documentation online at GitHub Pages.
Dependencies
The following dependencies are required to build ldfl:
- CMake (version 3.12 or higher)
- PCRE2 library
- Jansson library
- CUnit (optional, for tests)
- Doxygen (optional, for documentation)
On Ubuntu/Debian, you can install these dependencies with:
sudo apt update
sudo apt install -y cmake libpcre2-dev libjansson-dev libcunit1-dev doxygen
Development
- Clone the repository:
git clone https://github.com/kakwa/ldfl.git
cd ldfl
- Create a build directory and configure CMake:
- Build the project:
Optional build options:
-DBUILD_TESTS=ON
: Enable building tests
-DBUILD_DOC=ON
: Enable building documentation
-DCOVERAGE=ON
: Enable code coverage (requires -DBUILD_TESTS=ON
)
-DDEBUG=ON
: Build with debug symbols
-DSTATIC=ON
: Build static library
To run the tests & coverage
cmake . -DBUILD_TESTS=ON -DCOVERAGE=ON
make
make coverage
$BROWSER coverage/index.html
To build the documentation:
# Configure CMake
cmake -DBUILD_DOC=ON .
# Get Doxygen awesome CSS
./misc/setup_doxycss.sh
# Build Doc
make
# open the doc
$BROWSER ./docs/html/index.html
Installation
After building, you can install the library system-wide:
This will install:
- The library (
libldfl.so
) to /usr/local/lib/
- The wrapper executable (
ldfl-cli
) to /usr/local/bin/
Usage
Wrapper Usage
- Create a configuration file (e.g.,
config.json
) with your rule rules: ldfl-cli -c config.json -- your-application [args...]
To enable debug output, use the -d
flag:
ldfl-cli -d -c config.json -- your-application [args...]
If you need to specify a custom library path:
ldfl-cli -l /path/to/libldfl.so -c config.json -- your-application [args...]
Direct <tt>LD_PRELOAD</tt> Usage
You can use LDFL directly with LD_PRELOAD
without the wrapper:
# Set the configuration file
export LDFL_CONFIG=/path/to/config.json
# Preload the library
LD_PRELOAD=/path/to/libldfl.so your-application [args...]
JSON Configuration
The configuration file is a JSON file with two main sections: settings
and rules
.
Settings
The settings
section controls the logging behavior:
{
"settings": {
"log_mask": [
"rule_found",
"fn_call",
"init",
"rule_apply",
"rule_search",
"fn_call_err"
],
"log_level": "warning",
"logger": "syslog"
}
}
Available log masks:
rule_found
: Log when a rule rule is found
fn_call
: Log LibC function calls
init
: Log initialization operations
rule_apply
: Log when a rule rule is applied
rule_search
: Log rule search operations
fn_call_err
: Log LibC function call errors
Log levels:
Loggers:
syslog
: System logger
stderr
: Standard error output
dummy
: No logging
Mappings
The rules
section defines the file path rerule rules. Each rule has the following properties:
{
"rules": [
{
"name": "<descriptive/name>",
"search_pattern": "<regex pattern>",
"operation": "<operation type>",
"target": "<target path>",
"path_transform": "<absolute|original>",
"extra_options": "<operation specific options>",
"final": false
}
]
}
Available Operations
- File Redirection (
path_redir
): {
"name": "temp files redirect",
"search_pattern": ".*/temp/([^/]*)$",
"operation": "path_redir",
"target": "/tmp/$1",
"path_transform": "absolute",
"final": false
}
- Executable Redirection (
exec_redir
): {
"name": "executable redirect",
"search_pattern": ".*/.bin/\\([^/]*\\)$",
"operation": "exec_redir",
"target": "/opt/ldfl/bin/\\1",
"path_transform": "absolute",
"final": false
}
- Memory File (
mem_open
): {
"name": "memory open",
"search_pattern": ".*/file[0-9].txt",
"operation": "mem_open",
"target": null,
"path_transform": "absolute",
"final": false
}
- Static File (
mem_data
): {
"name": "static file",
"search_pattern": ".*/static.bin",
"operation": "mem_data",
"target": "default_blob",
"path_transform": "absolute",
"final": false
}
- Permission Change (
perm
): {
"name": "change data perm",
"search_pattern": ".*/data/.*",
"operation": "perm",
"target": null,
"path_transform": "absolute",
"final": false,
"extra_options": "user:group|dir_mode|file_mode"
}
- Access Control:
- Allow (
noop
): {
"name": "allow /dev",
"search_pattern": "^/dev/.*",
"operation": "noop",
"target": null,
"path_transform": "absolute",
"final": false
}
- Deny (
deny
): {
"name": "default & deny",
"search_pattern": ".*",
"operation": "deny",
"target": null,
"path_transform": "absolute",
"final": false
}
- Read-Only (
ro
): {
"name": "read only files",
"search_pattern": ".*/readonly/.*",
"operation": "ro",
"target": null,
"path_transform": "absolute",
"final": false
}
Embedding
For embedding LDFL in your project, copy over lib/ldfl.c
in your project.
Create a header file (e.g., ldfl-config.h
) with your configuration:
static const unsigned char ldf_default_blob[] = "hello from ldfl";
};
.log_level = LOG_WARNING,
.logger = ldfl_syslog_logger,
};
@ LDFL_PATH_ABS
Definition ldfl.c:49
@ LDFL_LOG_FN_CALL_ERR
Definition ldfl.c:62
@ LDFL_LOG_FN_CALL
Definition ldfl.c:61
@ LDFL_LOG_INIT
Definition ldfl.c:66
@ LDFL_OP_DENY
Definition ldfl.c:82
@ LDFL_OP_PATH_REDIR
Definition ldfl.c:76
@ LDFL_OP_PERM
Definition ldfl.c:80
@ LDFL_OP_MEM_OPEN
Definition ldfl.c:78
@ LDFL_OP_END
Definition ldfl.c:84
@ LDFL_OP_NOOP
Definition ldfl.c:75
@ LDFL_OP_MEM_DATA
Definition ldfl.c:79
@ LDFL_OP_EXEC_REDIR
Definition ldfl.c:77
Represents matching + operation rule.
Definition ldfl.c:125
Represents the general settings.
Definition ldfl.c:158
uint64_t log_mask
Definition ldfl.c:161
In your code, add:
#define LDFL_CONFIG "ldfl-config.h"
Structures of interest in ldfl.c.
Link against libpcre2 (-lpcre2-8
) if necessary.
And finally, build your project.