cyphar/libpathrs
GitHub: cyphar/libpathrs
Stars: 134 | Forks: 11
## `libpathrs`
[](https://docs.rs/pathrs/)
[](https://pkg.go.dev/cyphar.com/go-pathrs)
[](https://pypi.org/project/pathrs/)
[](Cargo.toml)
[](https://deps.rs/repo/github/cyphar/libpathrs)
[](https://codecov.io/github/cyphar/libpathrs)
[](https://github.com/cyphar/libpathrs/actions/workflows/rust.yml)
[](https://github.com/cyphar/libpathrs/actions/workflows/bindings-c.yml)
[](https://github.com/cyphar/libpathrs/actions/workflows/bindings-go.yml)
[](https://github.com/cyphar/libpathrs/actions/workflows/bindings-python.yml)
This library implements a set of C-friendly APIs (written in Rust) to make path
resolution within a potentially-untrusted directory safe on GNU/Linux. [There
are countless examples of security vulnerabilities caused by bad handling of
paths][avoidable-issues]; this library provides an easy-to-use set of VFS APIs
to avoid those kinds of issues.
### Examples
Here is a toy example of using this library to open a path (`/etc/passwd`)
inside a root filesystem (`/path/to/root`) safely. More detailed examples can
be found in `examples/` and `tests/`.
#### Rust
use std::fs::File;
use pathrs::{flags::OpenFlags, Root};
fn get_my_fd() -> Result {
const ROOT_PATH: &'static str = "/path/to/root";
const UNSAFE_PATH: &'static str = "/etc/passwd";
let root = Root::open(ROOT_PATH)?;
let handle = root.resolve(UNSAFE_PATH)?;
let file = handle.reopen(OpenFlags::O_RDONLY)?;
// The handle step can be skipped using root.open_subpath().
Ok(file)
}
#### C
#define _GNU_SOURCE
#include
#include
#include
#include
#include
#include
int get_my_fd(void)
{
const char *root_path = "/path/to/root";
const char *unsafe_path = "/etc/passwd";
int liberr = 0;
int root = -EBADF,
handle = -EBADF,
fd = -EBADF;
root = pathrs_open_root(root_path);
if (IS_PATHRS_ERR(root)) {
liberr = root;
goto err;
}
handle = pathrs_inroot_resolve(root, unsafe_path);
if (IS_PATHRS_ERR(handle)) {
liberr = handle;
goto err;
}
fd = pathrs_reopen(handle, O_RDONLY);
if (IS_PATHRS_ERR(fd)) {
liberr = fd;
goto err;
}
/* The handle step can be skipped using pathrs_inroot_open(). */
err:
if (IS_PATHRS_ERR(liberr)) {
pathrs_error_t *error = pathrs_errorinfo(liberr);
fprintf(stderr, "Uh-oh: %s (errno=%d)\n", error->description, error->saved_errno);
pathrs_errorinfo_free(error);
}
close(root);
close(handle);
return fd;
}
#### Go
package main
import (
"os"
"cyphar.com/go-pathrs"
)
func getMyFD() (*os.File, error) {
const rootPath = "/path/to/root"
const unsafePath = "/etc/passwd"
root, err := pathrs.OpenRoot(rootPath)
if err != nil {
return nil, err
}
defer root.Close()
handle, err := root.Resolve(unsafePath)
if err != nil {
return nil, err
}
defer handle.Close()
// The handle step can be skipped using root.Open().
return handle.Open()
}
On Linux, libpathrs also provides an API for safe `procfs` operations with
strict path safety [in the `procfs` module][docs.rs-procfs]. [Click
here][procfs-api] to see some concrete examples of its usage.
### License
`SPDX-License-Identifier: MPL-2.0 OR LGPL-3.0-or-later`
`libpathrs` is licensed under the terms of the [Mozilla Public License version
2.0][MPL-2.0] or the [GNU Lesser General Public License version 3][LGPL-3.0],
at your option.
Unless otherwise stated, by intentionally submitting any Contribution (as
defined by the Mozilla Public License version 2.0) for inclusion into the
`libpathrs` project, you are agreeing to dual-license your Contribution as
above, without any additional terms or conditions.
libpathrs: safe path resolution on Linux
Copyright (C) 2019-2025 SUSE LLC
Copyright (C) 2026 Aleksa Sarai
== MPL-2.0 ==
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at https://mozilla.org/MPL/2.0/.
Alternatively, this Source Code Form may also (at your option) be used
under the terms of the GNU Lesser General Public License Version 3, as
described below:
== LGPL-3.0-or-later ==
This program is free software: you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or (at
your option) any later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see .
#### Bindings
`SPDX-License-Identifier: MPL-2.0`
The language-specific bindings (the code in `contrib/bindings/` and
`go-pathrs/`) are licensed under the Mozilla Public License version 2.0
(available in [`LICENSE.MPL-2.0`][MPL-2.0]).
**NOTE**: If you compile `libpathrs.so` into your binary statically, you still
need to abide by the license terms of the main `libpathrs` project.
libpathrs: safe path resolution on Linux
Copyright (C) 2019-2025 SUSE LLC
Copyright (C) 2026 Aleksa Sarai
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at https://mozilla.org/MPL/2.0/.
#### Examples
`SPDX-License-Identifier: MPL-2.0`
The example code in `examples/` is licensed under the Mozilla Public License
version 2.0 (available in [`LICENSE.MPL-2.0`][MPL-2.0]).
libpathrs: safe path resolution on Linux
Copyright (C) 2019-2025 SUSE LLC
Copyright (C) 2026 Aleksa Sarai
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at https://mozilla.org/MPL/2.0/.
标签:通知系统