From 1feb98353f5ddd59eef1012af3219e3543d9b047 Mon Sep 17 00:00:00 2001 From: Aleksa Sarai Date: Wed, 2 Oct 2024 05:02:58 +0200 Subject: [PATCH] python bindings: add a minimal README Signed-off-by: Aleksa Sarai --- CHANGELOG.md | 2 + contrib/bindings/python/README.md | 85 ++++++++++++++++++++++++++ contrib/bindings/python/pyproject.toml | 2 + 3 files changed, 89 insertions(+) create mode 100644 contrib/bindings/python/README.md diff --git a/CHANGELOG.md b/CHANGELOG.md index 1e78daa..a53513d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] ## ### Fixes ### +- python bindings: add a minimal README for PyPI. + - python bindings: actually export `PROC_ROOT`. ## [0.1.1] - 2024-10-01 ## diff --git a/contrib/bindings/python/README.md b/contrib/bindings/python/README.md new file mode 100644 index 0000000..9fc8f6e --- /dev/null +++ b/contrib/bindings/python/README.md @@ -0,0 +1,85 @@ +## python-pathrs ## + +This is a basic Python wrapper around [libpathrs][libpathrs], a safe path +resolution library for Linux. For more details about the security protections +provided by [libpathrs][libpathrs], [see the main README][libpathrs-readme]. + +In order to use this library, you need to have `libpathrs.so` installed on your +system. + +### Examples ### + +libpathrs allows you to operate on a container root filesystem safely, without +worrying about an attacker swapping components and tricking you into operating +on host files. + +```python +import pathrs + +# Get a handle to the root filesystem. +with pathrs.Root("/path/to/rootfs") as root: + # Get an O_PATH handle to a path we want to operate on. + with root.resolve("/etc/passwd") as passwd: + # Upgrade the handle to one you can do regular IO on. + with root.reopen("r") as f: + for line in f: + print(line.rstrip("\n")) +``` + +Aside from just opening files, libpathrs also allows you to do most common +filesystem operations: + +```python +import pathrs + +# +RENAME_EXCHANGE = 0x2 + +with pathrs.Root("/path/to/rootfs") as root: + # symlink + root.symlink("foo", "bar") # foo -> bar + # link + root.hardlink("a", "b") # a -> b + # rename(at2) + root.rename("foo", "b", flags=RENAME_EXCHANGE) # foo <-> b + # open(O_CREAT) + with root.creat("newfile", "w+") as f: + f.write("Some contents.") +``` + +It also supports operations like `mkdir -p` and `rm -f`, which are a little +tricky to implement safely. + +```python +import pathrs + +with pathrs.Root("/path/to/rootfs") as root: + # rm -r + root.remove_all("/tmp/foo") + # mkdir -p + root.mkdir_all("/tmp/foo/bar/baz/bing/boop", 0o755) +``` + +In addition, libpathrs provides a safe `procfs` API, to allow for privileged +programs to operate on `/proc` in a way that detects a maliciously-configured +mount table. This is a somewhat esoteric requirement, but privileged processes +that have to operate in untrusted mount namespaces need to handle this +properly or risk serious security issues. + +```python +import pathrs + +# readlink("/proc/thread-self/fd/0") +stdin_path = pathrs.proc_readlink(pathrs.PROC_THREAD_SELF, "fd/0") + +# readlink("/proc/self/exe") +exe_path = pathrs.proc_readlink(pathrs.PROC_SELF, "exe") + +# Read data from /proc/cpuinfo. +with pathrs.proc_open(pathrs.PROC_ROOT, "cpuinfo", "r") as cpuinfo: + for line in cpuinfo: + print(line.rstrip("\n")) +``` + +[libpathrs]: https://github.com/openSUSE/libpathrs +[libpathrs-readme]: https://github.com/openSUSE/libpathrs/blob/main/README.md diff --git a/contrib/bindings/python/pyproject.toml b/contrib/bindings/python/pyproject.toml index 5470544..e4b7daa 100644 --- a/contrib/bindings/python/pyproject.toml +++ b/contrib/bindings/python/pyproject.toml @@ -29,6 +29,7 @@ name = "pathrs" # TODO: Figure out a way to keep this version up-to-date with Cargo.toml. version = "0.1.1+dev" description = "Python bindings for libpathrs, a safe path resolution library for Linux." +readme = "README.md" keywords = ["libpathrs", "pathrs"] license = { file = "COPYING.APACHE-2.0" } authors = [ @@ -57,3 +58,4 @@ dependencies = [ [project.urls] Homepage = "https://github.com/openSUSE/libpathrs" Repository = "https://github.com/openSUSE/libpathrs" +Documentation = "https://docs.rs/pathrs"