Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 0 additions & 30 deletions build.rs

This file was deleted.

3 changes: 3 additions & 0 deletions src/pam/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ mod securemem;
#[allow(nonstandard_style)]
pub mod sys;

#[link(name = "pam")]
extern "C" {}

#[cfg(target_os = "freebsd")]
const PAM_DATA_SILENT: std::ffi::c_int = 0;

Expand Down
5 changes: 3 additions & 2 deletions src/su/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,9 @@ use super::cli::SuRunOptions;
const VALID_LOGIN_SHELLS_LIST: &str = "/etc/shells";
const FALLBACK_LOGIN_SHELL: &str = "/bin/sh";

const PATH_DEFAULT: &str = env!("SU_PATH_DEFAULT");
const PATH_DEFAULT_ROOT: &str = env!("SU_PATH_DEFAULT_ROOT");
// TODO: use _PATH_STDPATH and _PATH_DEFPATH_ROOT from paths.h
const PATH_DEFAULT: &str = "/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games";
const PATH_DEFAULT_ROOT: &str = "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin";

#[derive(Debug)]
pub(crate) struct SuContext {
Expand Down
37 changes: 24 additions & 13 deletions src/sudo/env/environment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use std::{
collections::{HashMap, HashSet},
ffi::{OsStr, OsString},
os::unix::prelude::OsStrExt,
path::Path,
};

use crate::common::{CommandAndArguments, Context, Error};
Expand All @@ -10,8 +11,19 @@ use crate::system::PATH_MAX;

use super::wildcard_match::wildcard_match;

const PATH_ZONEINFO: &str = env!("PATH_ZONEINFO");
const PATH_DEFAULT: &str = env!("SUDO_PATH_DEFAULT");
fn path_zoneinfo() -> Option<&'static str> {
[
"/usr/share/zoneinfo",
"/usr/share/lib/zoneinfo",
"/usr/lib/zoneinfo",
"/usr/lib/zoneinfo",
]
.into_iter()
.find(|p| Path::new(p).exists())
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: a temptation here would be to add a "audit.rs"-like check that the path should not be user-writable. But of course in this scenario that actually weakens the security. I'd suggest adding a comment here that adding a "writeability" check here is deliberately ommitted.

}

// TODO: use _PATH_STDPATH from paths.h
pub(crate) const PATH_DEFAULT: &str = "/usr/bin:/bin:/usr/sbin:/sbin";

pub type Environment = HashMap<OsString, OsString>;

Expand Down Expand Up @@ -138,12 +150,9 @@ fn is_safe_tz(value: &[u8]) -> bool {
};

if check_value.starts_with(b"/") {
// clippy 1.79 wants to us to optimise this check away; but we don't know what this will always
// be possible; and the compiler is clever enough to do that for us anyway if it can be.
#[allow(clippy::const_is_empty)]
if !PATH_ZONEINFO.is_empty() {
if !check_value.starts_with(PATH_ZONEINFO.as_bytes())
|| check_value.get(PATH_ZONEINFO.len()) != Some(&b'/')
if let Some(path_zoneinfo) = path_zoneinfo() {
if !check_value.starts_with(path_zoneinfo.as_bytes())
|| check_value.get(path_zoneinfo.len()) != Some(&b'/')
{
return false;
}
Expand Down Expand Up @@ -255,7 +264,7 @@ where

#[cfg(test)]
mod tests {
use super::{is_safe_tz, should_keep, PATH_ZONEINFO};
use super::{is_safe_tz, path_zoneinfo, should_keep};
use std::{collections::HashSet, ffi::OsStr};

struct TestConfiguration {
Expand Down Expand Up @@ -317,25 +326,27 @@ mod tests {
#[allow(clippy::bool_assert_comparison)]
#[test]
fn test_tzinfo() {
let path_zoneinfo = path_zoneinfo().unwrap();
assert_eq!(is_safe_tz("Europe/Amsterdam".as_bytes()), true);
assert_eq!(
is_safe_tz(format!("{PATH_ZONEINFO}/Europe/London").as_bytes()),
is_safe_tz(format!("{path_zoneinfo}/Europe/London").as_bytes()),
true
);
assert_eq!(
is_safe_tz(format!(":{PATH_ZONEINFO}/Europe/Amsterdam").as_bytes()),
is_safe_tz(format!(":{path_zoneinfo}/Europe/Amsterdam").as_bytes()),
true
);
assert_eq!(is_safe_tz(format!("/Europe/Amsterdam").as_bytes()), false);
assert_eq!(
is_safe_tz(format!("/schaap/Europe/Amsterdam").as_bytes()),
false
);
assert_eq!(
is_safe_tz(format!("{PATH_ZONEINFO}/../Europe/London").as_bytes()),
is_safe_tz(format!("{path_zoneinfo}/../Europe/London").as_bytes()),
false
);
assert_eq!(
is_safe_tz(format!("{PATH_ZONEINFO}/../Europe/London").as_bytes()),
is_safe_tz(format!("{path_zoneinfo}/../Europe/London").as_bytes()),
false
);
}
Expand Down
1 change: 1 addition & 0 deletions src/sudo/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ mod edit;

pub(crate) mod diagnostic;
mod env;
pub(crate) use env::environment::PATH_DEFAULT;
mod pam;
mod pipeline;

Expand Down
2 changes: 1 addition & 1 deletion src/sudoers/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -321,7 +321,7 @@ fn select_editor(settings: &Settings, trusted_env: bool) -> PathBuf {
editor
} else if let Some(editor) = resolve_path(
&editor,
&std::env::var("PATH").unwrap_or(env!("SUDO_PATH_DEFAULT").to_string()),
&std::env::var("PATH").unwrap_or(crate::sudo::PATH_DEFAULT.to_string()),
) {
editor
} else {
Expand Down
Loading