From 5f5f3e03cf20e9caebf8a5ae9aab022e24aec0ea Mon Sep 17 00:00:00 2001 From: Ethan Pailes Date: Mon, 15 Jul 2024 15:24:32 +0000 Subject: [PATCH] fix: mark PIDFDInfo and PIDRUsage unsafe This patch marks the PIDRUsage and PIDFDInfo traits as unsafe, since incorrect implementations of these traits could lead to unsound behavior. Unfortunately, since these are public traits, this will mean an incompatible version bump for the next release, though hopefully no one is really rolling their own implementation for these guys. https://doc.rust-lang.org/reference/unsafe-keyword.html#unsafe-traits-unsafe-trait --- src/libproc/file_info.rs | 8 +++++++- src/libproc/net_info.rs | 6 +++++- src/libproc/pid_rusage.rs | 33 +++++++++++++++++++++++++++------ 3 files changed, 39 insertions(+), 8 deletions(-) diff --git a/src/libproc/file_info.rs b/src/libproc/file_info.rs index eccfbe15..6818a65d 100644 --- a/src/libproc/file_info.rs +++ b/src/libproc/file_info.rs @@ -89,7 +89,13 @@ impl From for ProcFDType { /// The `PIDFDInfo` trait is needed for polymorphism on pidfdinfo types, also abstracting flavor /// in order to provide type-guaranteed flavor correctness -pub trait PIDFDInfo: Default { +/// +/// # Safety +/// +/// The type this trait is implemented on must be correctly sized such that +/// a pointer to that type can be passed to the libproc `proc_pidfdinfo` function +/// as the buffer parameter. +pub unsafe trait PIDFDInfo: Default { /// Return the Pid File Descriptor Info flavor of the implementing struct fn flavor() -> PIDFDInfoFlavor; } diff --git a/src/libproc/net_info.rs b/src/libproc/net_info.rs index a2b3162b..bf85421e 100644 --- a/src/libproc/net_info.rs +++ b/src/libproc/net_info.rs @@ -35,7 +35,11 @@ pub struct ProcFileInfo { pub rfu_1: i32, } -impl PIDFDInfo for SocketFDInfo { +/// # Saftey +/// +/// The size of SocketFDInfo is correct for getting passed to +/// proc_pidfdinfo. +unsafe impl PIDFDInfo for SocketFDInfo { fn flavor() -> PIDFDInfoFlavor { PIDFDInfoFlavor::SocketInfo } diff --git a/src/libproc/pid_rusage.rs b/src/libproc/pid_rusage.rs index 882bd567..1cd7cedd 100644 --- a/src/libproc/pid_rusage.rs +++ b/src/libproc/pid_rusage.rs @@ -11,7 +11,13 @@ use crate::osx_libproc_bindings::proc_pid_rusage; /// The `PIDRUsage` trait is needed for polymorphism on pidrusage types, also abstracting flavor in order to provide /// type-guaranteed flavor correctness -pub trait PIDRUsage: Default { +/// +/// # Safety +/// +/// The type this trait is implemented on must be correctly sized such that +/// a pointer to that type can be passed to the libproc `proc_pid_rusage` function +/// as the buffer parameter. +pub unsafe trait PIDRUsage: Default { /// Return the `PidRUsageFlavor` for the implementing struct fn flavor() -> PidRUsageFlavor; /// Memory used in bytes @@ -62,7 +68,10 @@ pub struct RUsageInfoV0 { pub ri_proc_exit_abstime: u64, } -impl PIDRUsage for RUsageInfoV0 { +/// # Safety +/// +/// The size is appropriate for getting passed to pidrusage. +unsafe impl PIDRUsage for RUsageInfoV0 { fn flavor() -> PidRUsageFlavor { PidRUsageFlavor::V0 } @@ -116,7 +125,10 @@ pub struct RUsageInfoV1 { pub ri_child_elapsed_abstime: u64, } -impl PIDRUsage for RUsageInfoV1 { +/// # Safety +/// +/// The size is appropriate for getting passed to pidrusage. +unsafe impl PIDRUsage for RUsageInfoV1 { fn flavor() -> PidRUsageFlavor { PidRUsageFlavor::V1 } @@ -174,7 +186,10 @@ pub struct RUsageInfoV2 { pub ri_diskio_byteswritten: u64, } -impl PIDRUsage for RUsageInfoV2 { +/// # Safety +/// +/// The size is appropriate for getting passed to pidrusage. +unsafe impl PIDRUsage for RUsageInfoV2 { fn flavor() -> PidRUsageFlavor { PidRUsageFlavor::V2 } @@ -250,7 +265,10 @@ pub struct RUsageInfoV3 { pub ri_serviced_system_time: u64, } -impl PIDRUsage for RUsageInfoV3 { +/// # Safety +/// +/// The size is appropriate for getting passed to pidrusage. +unsafe impl PIDRUsage for RUsageInfoV3 { fn flavor() -> PidRUsageFlavor { PidRUsageFlavor::V3 } @@ -342,7 +360,10 @@ pub struct RUsageInfoV4 { pub ri_unused: [u64; 1], } -impl PIDRUsage for RUsageInfoV4 { +/// # Safety +/// +/// The size is appropriate for getting passed to pidrusage. +unsafe impl PIDRUsage for RUsageInfoV4 { fn flavor() -> PidRUsageFlavor { PidRUsageFlavor::V4 }