make ldd / where features optional

This commit is contained in:
atagen 2025-11-03 16:41:38 +11:00
parent 5766b0cdfe
commit ab083b07e4
3 changed files with 29 additions and 14 deletions

View file

@ -2,11 +2,17 @@
name = "yoke"
version = "0.1.0"
authors = [ "atagen" ]
description = "A simple sandboxing tool, similar to bwrap"
description = "CLI sandboxing tool similar to landrun or bwrap"
repository = "https://git.atagen.co/atagen/yoke"
license = "GPL-3.0-or-later"
edition = "2024"
[features]
default = []
ldd = ["dep:elb-dl"]
which = ["dep:which"]
[profile.release]
strip = true
opt-level = "s"
@ -14,7 +20,7 @@ codegen-units = 1
[dependencies]
anyhow = "1.0.100"
elb-dl = { version = "0.3.2", features = ["glibc"], default-features = false }
exec = "0.3.1"
landlock = "0.4.3"
which = "8.0.0"
exec = "0.3.1"
elb-dl = { version = "0.3.2", features = ["glibc"], default-features = false, optional = true }
which = { version = "8.0.0", optional = true }

View file

@ -1,25 +1,28 @@
mod parse;
mod types;
use std::{collections::VecDeque, path::PathBuf, str::FromStr};
use anyhow::{Context, Result, anyhow};
use elb_dl::{DependencyTree, DynamicLoader, glibc};
use landlock::{
ABI, Access, AccessFs, AccessNet, BitFlags, Compatible, NetPort, Ruleset, RulesetAttr,
RulesetCreatedAttr, Scope, make_bitflags, path_beneath_rules,
};
#[cfg(feature = "ldd")]
use elb_dl::{DependencyTree, DynamicLoader, glibc};
#[cfg(feature = "ldd")]
use std::{collections::VecDeque, path::PathBuf, str::FromStr};
fn main() -> Result<()> {
let opts = parse::parse_args()?;
if opts.exec.is_empty() {
// print help
eprintln!(
"
yoke -- simple command sandboxer
yoke -- simple sandboxer
use: yoke [ruletype] [space separated rules] -- [command]
rule types
rules
------------
filesystem:
--fs | -f [access]=/path:/another/path
@ -39,7 +42,8 @@ rule types
allow sending signals to other processes:
--signals | -k
resolve process dependencies and add to sandbox:
resolve process dependencies and add to sandbox
(with `ldd` feature):
--ldd | -l
unsandbox:
@ -47,7 +51,7 @@ rule types
--no-tcp | -nt
specifiers
access specifiers
------------
fs:
r - read
@ -165,7 +169,11 @@ examples
}
// locate our executable
#[cfg(feature = "which")]
let fullpath = which::which(&opts.exec[0]).context("finding executable")?;
#[cfg(not(feature = "which"))]
let fullpath = &opts.exec[0];
// add executeable as read+execute
if !opts.unsandbox.fs {
ruleset = ruleset.add_rules(path_beneath_rules(
@ -175,12 +183,10 @@ examples
}
// if requested, trace dependencies and add as read+execute
#[cfg(feature = "ldd")]
if opts.ldd {
let loader = DynamicLoader::options()
.search_dirs(glibc::get_hard_coded_search_dirs(None)?)
.search_dirs(glibc::get_search_dirs(
PathBuf::from_str("/").context("finding root")?,
)?)
.new_loader();
let mut tree = DependencyTree::new();
let mut queue = VecDeque::new();

View file

@ -1,5 +1,5 @@
use crate::types::{Direction, Permissions, Yoke};
use anyhow::{anyhow, Context, Result};
use anyhow::{Context, Result, anyhow};
use std::{collections::HashMap, path::PathBuf, str::FromStr};
#[derive(PartialEq)]
@ -145,12 +145,15 @@ pub fn parse_args() -> Result<Yoke> {
cur_arg = Unset;
yoke.retain_env = true;
}
#[cfg(feature = "ldd")]
"--ldd" | "-l" => {
collect_args(&mut yoke, &collector, &cur_arg)?;
collector.clear();
cur_arg = Unset;
yoke.ldd = true;
}
"--no-fs" | "-nf" => {
collect_args(&mut yoke, &collector, &cur_arg)?;
collector.clear();