cyphar/libpathrs

GitHub: cyphar/libpathrs

一个用 Rust 编写的 Linux 路径解析安全库,通过提供对 C 友好的 VFS API 来防止在不受信任目录中的路径处理漏洞。

Stars: 135 | Forks: 12

## `libpathrs` [![rust 文档](https://img.shields.io/docsrs/pathrs?logo=rust&logoColor=white&color=orange)](https://docs.rs/pathrs/) [![go 文档](https://pkg.go.dev/badge/cyphar.com/go-pathrs.svg)](https://pkg.go.dev/cyphar.com/go-pathrs) [![PyPI 包](https://img.shields.io/pypi/v/pathrs?logo=python&logoColor=white)](https://pypi.org/project/pathrs/) [![msrv](https://img.shields.io/crates/msrv/pathrs?logo=rust&logoColor=white)](Cargo.toml) [![依赖状态](https://deps.rs/repo/github/cyphar/libpathrs/status.svg)](https://deps.rs/repo/github/cyphar/libpathrs) [![codecov](https://codecov.io/github/cyphar/libpathrs/graph/badge.svg?token=ITPWXADXPC)](https://codecov.io/github/cyphar/libpathrs) [![rust-ci 构建状态](https://static.pigsec.cn/wp-content/uploads/repos/cas/7d/7dc08d12716c67bef0db51a77ba1394ecb7e5de97b9ded7e029cb6da6e1e93ee.svg)](https://github.com/cyphar/libpathrs/actions/workflows/rust.yml) [![bindings-c 构建状态](https://static.pigsec.cn/wp-content/uploads/repos/cas/c4/c48a0bbd5b670aad690461987c1d34ad6a67a95e3e6114d922cb4b5d0607cd5a.svg)](https://github.com/cyphar/libpathrs/actions/workflows/bindings-c.yml) [![bindings-go 构建状态](https://static.pigsec.cn/wp-content/uploads/repos/cas/a6/a6c59c95bcc2aa80880682815919de503213c93092752072462c8e905a7b3584.svg)](https://github.com/cyphar/libpathrs/actions/workflows/bindings-go.yml) [![bindings-python 构建状态](https://static.pigsec.cn/wp-content/uploads/repos/cas/92/92b0952c101925e62b6cf32c34a6ffb00c5d6978c8d3fbdc863a29f4543e4d08.svg)](https://github.com/cyphar/libpathrs/actions/workflows/bindings-python.yml) 本库实现了一组对 C 友好的 API(使用 Rust 编写),旨在使在潜在不受信任的目录中进行路径解析在 GNU/Linux 上变得安全。[有无数因不当处理路径而导致安全漏洞的例子][avoidable-issues];本库提供了一组易于使用的 VFS API 来避免此类问题。 ### 示例 以下是一个使用本库在根文件系统(`/path/to/root`)中安全打开路径(`/etc/passwd`)的简单示例。更详细的示例可以在 `examples/` 和 `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() } ``` 在 Linux 上,libpathrs 还提供了一个用于安全 `procfs` 操作的 API,并在 [`procfs` 模块][docs.rs-procfs]中实现了严格的路径安全。[点击这里][procfs-api]查看其用法的具体示例。 ### 内核支持 目前,`libpathrs` 仅适用于 Linux,因为它是围绕提供安全路径操作所必需的 Linux 专有 API 设计的。未来,我们计划扩展对其他类 Unix 操作系统的支持。 尽管 `libpathrs` 可以在非常旧的内核上运行(理论上可追溯至 Linux 2.6.39,尽管我们目前未对此进行测试),但我们*强烈*建议至少使用 Linux 5.6,以获得针对各种攻击的合理保护。目前支持[我们用于强化的所有功能][kernel-feature-list]的最低 Linux 内核版本是 Linux 6.8。 ### 许可证 `SPDX-License-Identifier: MPL-2.0 OR LGPL-3.0-or-later` `libpathrs` 根据您的选择,采用 [Mozilla Public License version 2.0][MPL-2.0] 或 [GNU Lesser General Public License version 3][LGPL-3.0] 的条款进行许可。 除非另有说明,否则通过有意提交任何贡献(定义见 Mozilla Public License version 2.0)以包含在 `libpathrs` 项目中,即表示您同意按上述方式对您的贡献进行双重许可,且不附带任何额外的条款或条件。 ``` 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 . ``` #### 绑定 `SPDX-License-Identifier: MPL-2.0` 特定语言的绑定(`contrib/bindings/` 和 `go-pathrs/` 中的代码)采用 Mozilla Public License version 2.0(详见 [`LICENSE.MPL-2.0`][MPL-2.0])进行许可。 **注意**:如果您将 `libpathrs.so` 静态编译到您的二进制文件中,您仍需遵守主要 `libpathrs` 项目的许可条款。 ``` 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/. ``` #### 示例 `SPDX-License-Identifier: MPL-2.0` `examples/` 中的示例代码采用 Mozilla Public License version 2.0(详见 [`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/. ```
标签:Rust, 可视化界面, 安全防护, 日志审计, 系统开发, 网络流量审计, 路径解析, 逆向工具, 通知系统