From 4ecaefba72b5c5321b5469614c7da910cc046caa Mon Sep 17 00:00:00 2001
From: titison
Date: Sat, 11 Nov 2023 20:44:08 +0100
Subject: [PATCH 1/3] MachO: display complete @rpath
---
README.md | 1 -
src/macho.rs | 30 ++++++++++++------------------
2 files changed, 12 insertions(+), 19 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..1bd6147 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
)
}
}
@@ -173,9 +171,8 @@ 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 {
@@ -264,18 +261,15 @@ 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]);
+ } else {
+ let mut rpath_vec = Vec::with_capacity(self.rpaths.len());
+ for i in &self.rpaths {
+ rpath_vec.push(Rpath::Yes(i.to_string()));
}
+ return VecRpath::new(rpath_vec);
}
- //VecRpath::new(vec![Rpath::None])
- false
}
}
From d6fb6bae05ae479e6130f73693a921aa65c1fda3 Mon Sep 17 00:00:00 2001
From: titison
Date: Sat, 11 Nov 2023 23:58:09 +0100
Subject: [PATCH 2/3] MachO: check symbols instead of imports. fixes issue #44
---
src/macho.rs | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/src/macho.rs b/src/macho.rs
index 1bd6147..f47f600 100644
--- a/src/macho.rs
+++ b/src/macho.rs
@@ -176,9 +176,9 @@ pub trait Properties {
}
impl Properties for MachO<'_> {
fn has_arc(&self) -> bool {
- if let Ok(imports) = self.imports() {
- for import in &imports {
- if import.name == "_objc_release" {
+ for i in self.symbols() {
+ if let Ok((symbol,_)) = i {
+ if symbol == "_objc_release" {
return true;
}
}
@@ -186,9 +186,9 @@ impl Properties for MachO<'_> {
false
}
fn has_canary(&self) -> bool {
- if let Ok(imports) = self.imports() {
- for import in &imports {
- match import.name {
+ for i in self.symbols() {
+ if let Ok((symbol,_)) = i {
+ match symbol {
"___stack_chk_fail" | "___stack_chk_guard" => return true,
_ => continue,
}
From a0100a90381616bb17d105d2e6fa6a85cb4c16c4 Mon Sep 17 00:00:00 2001
From: titison
Date: Sun, 12 Nov 2023 00:09:23 +0100
Subject: [PATCH 3/3] MachO: Check swift symbols for arc and canary. Fixes #6
`_swift_release` is the ARC symbol for swift according to:
https://stackoverflow.com/questions/34700937/profiling-swift-with-instruments-what-exactly-is-swift-retain
`___chkstk_darwin` is the Stack Canary symbol for swift according to:
https://forums.swift.org/t/what-is-chkstk-darwin/59519
---
src/macho.rs | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/src/macho.rs b/src/macho.rs
index f47f600..271f922 100644
--- a/src/macho.rs
+++ b/src/macho.rs
@@ -150,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;
@@ -178,8 +178,9 @@ impl Properties for MachO<'_> {
fn has_arc(&self) -> bool {
for i in self.symbols() {
if let Ok((symbol,_)) = i {
- if symbol == "_objc_release" {
- return true;
+ match symbol {
+ "_objc_release" | "_swift_release" => return true,
+ _ => continue,
}
}
}
@@ -189,7 +190,7 @@ impl Properties for MachO<'_> {
for i in self.symbols() {
if let Ok((symbol,_)) = i {
match symbol {
- "___stack_chk_fail" | "___stack_chk_guard" => return true,
+ "___stack_chk_fail" | "___stack_chk_guard" | "___chkstk_darwin" => return true,
_ => continue,
}
}