1
1
mirror of https://github.com/wez/wezterm.git synced 2024-11-22 22:42:48 +03:00

apply executable checks to $SHELL and /etc/passwd lookup

refs: https://github.com/wez/wezterm/issues/2378
This commit is contained in:
Wez Furlong 2022-08-09 20:12:28 -07:00
parent 9cd72fefe2
commit 6542566e8f

View File

@ -449,22 +449,37 @@ impl CommandBuilder {
/// We take the contents of the $SHELL env var first, then
/// fall back to looking it up from the password database.
pub fn get_shell(&self) -> anyhow::Result<String> {
use nix::unistd::{access, AccessFlags};
use std::ffi::CStr;
use std::path::Path;
use std::str;
if let Some(shell) = self.get_env("SHELL").and_then(OsStr::to_str) {
return Ok(shell.into());
match access(shell, AccessFlags::X_OK) {
Ok(()) => return Ok(shell.into()),
Err(err) => log::warn!(
"$SHELL -> {shell:?} which is \
not executable ({err:#}), falling back to password db lookup"
),
}
}
let ent = unsafe { libc::getpwuid(libc::getuid()) };
if ent.is_null() {
Ok("/bin/sh".into())
} else {
use std::ffi::CStr;
use std::str;
if !ent.is_null() {
let shell = unsafe { CStr::from_ptr((*ent).pw_shell) };
shell
let shell = shell
.to_str()
.map(str::to_owned)
.context("failed to resolve shell")
.context("failed to resolve shell from passwd database")?;
if let Err(err) = access(Path::new(&shell), AccessFlags::X_OK) {
log::warn!(
"passwd database shell={shell:?} which is \
not executable ({err:#}), fallback to /bin/sh"
);
}
}
Ok("/bin/sh".into())
}
fn get_home_dir(&self) -> anyhow::Result<String> {