From de2c270c315a69ddd936df4496228b815f90e0a2 Mon Sep 17 00:00:00 2001 From: Marco Grassi Date: Thu, 23 May 2024 16:22:40 +0800 Subject: [PATCH] port https://github.com/etke/checksec.rs/pull/45 by @titison --- README.md | 1 - src/macho.rs | 55 ++++++++++++++++++++++------------------------------ 2 files changed, 23 insertions(+), 33 deletions(-) diff --git a/README.md b/README.md index 39ace19..a20ae93 100644 --- a/README.md +++ b/README.md @@ -141,7 +141,6 @@ See [examples/](https://github.com/etke/checksec.rs/tree/master/examples) for li * Rpath RW * Platform independent checks * MachO - * `@rpath` contents into `shared::VecRpath` similar to `DT_RPATH`/`DT_RUNPATH` on ELFs * Code signature validation ### checksec todos diff --git a/src/macho.rs b/src/macho.rs index 13015f2..2425490 100644 --- a/src/macho.rs +++ b/src/macho.rs @@ -8,7 +8,7 @@ use std::fmt; #[cfg(feature = "color")] use crate::colorize_bool; -//use crate::shared::{Rpath, VecRpath}; +use crate::shared::{Rpath, VecRpath}; const MH_ALLOW_STACK_EXECUTION: u32 = 0x0002_0000; const MH_PIE: u32 = 0x0020_0000; @@ -55,8 +55,7 @@ pub struct CheckSecResults { /// Restrict segment pub restrict: bool, /// Load Command @rpath - //rpath: VecRpath, - pub rpath: bool, + pub rpath: VecRpath, } impl CheckSecResults { #[must_use] @@ -127,8 +126,7 @@ impl fmt::Display for CheckSecResults { "Restrict:".bold(), colorize_bool!(self.restrict), "RPath:".bold(), - //self.rpath - colorize_bool!(self.rpath) + self.rpath, ) } } @@ -152,9 +150,9 @@ impl fmt::Display for CheckSecResults { /// } /// ``` pub trait Properties { - /// check import names for `_objc_release` + /// check symbol names for `_objc_release` or `_swift_release` fn has_arc(&self) -> bool; - /// check import names for `___stack_chk_fail` or `___stack_chk_guard` + /// check symbol names for `___stack_chk_fail` `___stack_chk_guard` or `___chkstk_darwin` fn has_canary(&self) -> bool; /// check data size of code signature in load commands fn has_code_signature(&self) -> bool; @@ -173,28 +171,25 @@ pub trait Properties { fn has_pie(&self) -> bool; /// check for `___restrict` segment name fn has_restrict(&self) -> bool; - //fn has_rpath(&self) -> VecRpath; /// check for `RPath` in load commands - fn has_rpath(&self) -> bool; + fn has_rpath(&self) -> VecRpath; } impl Properties for MachO<'_> { fn has_arc(&self) -> bool { - if let Ok(imports) = self.imports() { - for import in &imports { - if import.name == "_objc_release" { - return true; - } + for (symbol, _) in self.symbols().flatten() { + match symbol { + "_objc_release" | "_swift_release" => return true, + _ => continue, } } false } fn has_canary(&self) -> bool { - if let Ok(imports) = self.imports() { - for import in &imports { - match import.name { - "___stack_chk_fail" | "___stack_chk_guard" => return true, - _ => continue, - } + for (symbol, _) in self.symbols().flatten() { + match symbol { + "___stack_chk_fail" | "___stack_chk_guard" + | "___chkstk_darwin" => return true, + _ => continue, } } false @@ -264,18 +259,14 @@ impl Properties for MachO<'_> { } false } - //fn has_rpath(&self) -> VecRpath { - fn has_rpath(&self) -> bool { - // simply check for existence of @rpath command for now - // parse out rpath entries similar to elf later - // paths separated by `;` instead of `:` like the elf counterpart - for loadcmd in &self.load_commands { - if let CommandVariant::Rpath(_) = loadcmd.command { - return true; - //return VecRpath::new(vec![Rpath::Yes("true".to_string())]); - } + fn has_rpath(&self) -> VecRpath { + if self.rpaths.is_empty() { + return VecRpath::new(vec![Rpath::None]); } - //VecRpath::new(vec![Rpath::None]) - false + let mut rpath_vec = Vec::with_capacity(self.rpaths.len()); + for i in &self.rpaths { + rpath_vec.push(Rpath::Yes((*i).to_string())); + } + VecRpath::new(rpath_vec) } }