/// Generate a table of 256 entries that which each single, or **OR**-combined mask entry of `UntrustedPathRules` has a corresponding path check function.
///
/// Invalid functions will either:
/// * Panic if they are *never* supposed to be called in the pipeline (e.g `NAME_MATCH`.)
//TODO: Add in combinations via ORing its single-bit entry functions.
rule_table
}
/// Generate a table of 256 entries that which each **single** (not combinations of) entry of `UntrustedPathRules` has a corresponding path check function.
//XXX: Should we use process's UID or EUID? It seems we should use EUID.
fngeteuid()-> u32;// uid_t
}
// SAFETY: This is a pure function for all that matters.
letuser_id=unsafe{geteuid()};
path.metadata()
.map(move|meta|meta.uid()==user_id)
.unwrap_or(false)
});
set!(USER_ACCESSIBLE_ONLY=>|path,_|{
//Only Owner should be able to read, write, or execute.
usestd::os::unix::fs::PermissionsExtas_;
usereadable_perms::{
User,
Bit,
};
constBIT_ANY: Bit=
Bit::Read
.union(Bit::Write)
.union(Bit::Execute);
constOTHER_ACCESSORS: u32=
User::Group.mode(BIT_ANY)
|User::Other.mode(BIT_ANY);
path.metadata()
.map(|meta|!meta.permissions().mode()&OTHER_ACCESSORS==0)//XXX: Test this
.unwrap_or(false)
});
//TODO: Composition of functions should be done via OR, how to insert all possible compositions into table? We get confusing error messages when we try inside `set!()`
table
}
}
implDefaultforUntrustedPathRules
{
#[inline]
@ -103,10 +252,10 @@ pub mod locations {
/// Should symlinks be followed in a recursive lookup. (0 is for trusted paths, 1 is for untrusted)
todo!("TODO: extra Untrusted lookup rules checked on `path` here.")
}
@ -251,42 +418,43 @@ impl PathLookup
letpath=path.as_ref();
// Check if the path:
// * Exists
// * Is not a directory
// NOTE: We don't use `.is_file()` here, because we want to support symlinks and pseudofiles in trusted contexts, which `is_file()` reports as false.
// TODO: XXX: Maybe in the future allow directories to be plugins; they would contain a manifest, and each `.so` file in the directory will be loaded in order specified by the directory's manifest.
if!path.exists()||path.is_dir(){
returnfalse;
}
// Attempt to extract the filename, return false if it is invalid UTF8.
letfilename=matchpath.file_name()
.and_then(|os_fn|os_fn.to_str())
{
Some(f)=>f,
_=>returnfalse,
};
// trait Checker // XXX: Was used for dynamic dispatch in the `if Trusted ...` block below, but is no longer needed as Trusted will never have one, and untrusted will always have the same one; we can just use Option<impl FnOnce> pretty much