Skip to content

Commit

Permalink
fix: mark PIDFDInfo and PIDRUsage unsafe
Browse files Browse the repository at this point in the history
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
  • Loading branch information
ethanpailes committed Jul 29, 2024
1 parent cb8c2ab commit 3e42c03
Show file tree
Hide file tree
Showing 8 changed files with 81 additions and 16 deletions.
3 changes: 3 additions & 0 deletions src/libproc/bsd_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ use crate::libproc::proc_pid::{PIDInfo, PidInfoFlavor};
#[cfg(target_os = "macos")]
pub use crate::osx_libproc_bindings::proc_bsdinfo as BSDInfo;

/// # Safety
///
/// `BSDInfo` is correctly sized and flavor indicates the right struct.
#[cfg(target_os = "macos")]
impl PIDInfo for BSDInfo {
fn flavor() -> PidInfoFlavor {
Expand Down
13 changes: 11 additions & 2 deletions src/libproc/file_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,10 @@ pub enum PIDFDInfoFlavor {
/// Struct for Listing File Descriptors
pub struct ListFDs;

impl ListPIDInfo for ListFDs {
/// # Safety
///
/// `Item` is correctly sized and the flavor matches.
unsafe impl ListPIDInfo for ListFDs {
type Item = ProcFDInfo;
fn flavor() -> PidInfoFlavor {
PidInfoFlavor::ListFDs
Expand Down Expand Up @@ -89,7 +92,13 @@ impl From<u32> 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;
}
Expand Down
6 changes: 5 additions & 1 deletion src/libproc/net_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand Down
33 changes: 27 additions & 6 deletions src/libproc/pid_rusage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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 `proc_pid_pidrusage`.
unsafe impl PIDRUsage for RUsageInfoV0 {
fn flavor() -> PidRUsageFlavor {
PidRUsageFlavor::V0
}
Expand Down Expand Up @@ -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 `proc_pid_pidrusage`.
unsafe impl PIDRUsage for RUsageInfoV1 {
fn flavor() -> PidRUsageFlavor {
PidRUsageFlavor::V1
}
Expand Down Expand Up @@ -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 `proc_pid_pidrusage`.
unsafe impl PIDRUsage for RUsageInfoV2 {
fn flavor() -> PidRUsageFlavor {
PidRUsageFlavor::V2
}
Expand Down Expand Up @@ -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 `proc_pid_pidrusage`.
unsafe impl PIDRUsage for RUsageInfoV3 {
fn flavor() -> PidRUsageFlavor {
PidRUsageFlavor::V3
}
Expand Down Expand Up @@ -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 `proc_pid_pidrusage`.
unsafe impl PIDRUsage for RUsageInfoV4 {
fn flavor() -> PidRUsageFlavor {
PidRUsageFlavor::V4
}
Expand Down
22 changes: 19 additions & 3 deletions src/libproc/proc_pid.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,13 @@ pub enum ProcType {

/// The `PIDInfo` trait is needed for polymorphism on pidinfo types, also abstracting flavor in order to provide
/// type-guaranteed flavor correctness
pub trait PIDInfo {
///
/// # 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_pidinfo` function
/// as the buffer parameter.
pub unsafe trait PIDInfo {
/// Return the `PidInfoFlavor` of the implementing struct
fn flavor() -> PidInfoFlavor;
}
Expand Down Expand Up @@ -126,7 +132,14 @@ pub enum PidInfo {

/// The `ListPIDInfo` trait is needed for polymorphism on listpidinfo types, also abstracting flavor in order to provide
/// type-guaranteed flavor correctness
pub trait ListPIDInfo {
///
/// # Safety
///
/// The `Item` type associated with this trait on must be correctly sized such that
/// a pointer to an array of that type can be passed to the libproc
/// `proc_pidinfo` function as the buffer parameter, with the `flavor()`
/// value indicating the correct output type.
pub unsafe trait ListPIDInfo {
/// Item
type Item;
/// Return the `PidInfoFlavor` of the implementing struct
Expand All @@ -136,7 +149,10 @@ pub trait ListPIDInfo {
/// Struct for List of Threads
pub struct ListThreads;

impl ListPIDInfo for ListThreads {
/// # Safety
///
/// `Item` is correctly sized and the flavor matches.
unsafe impl ListPIDInfo for ListThreads {
type Item = u64;
fn flavor() -> PidInfoFlavor {
PidInfoFlavor::ListThreads
Expand Down
10 changes: 8 additions & 2 deletions src/libproc/task_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,11 @@ use crate::libproc::proc_pid::{PIDInfo, PidInfoFlavor};
#[cfg(target_os = "macos")]
pub use crate::osx_libproc_bindings::proc_taskinfo as TaskInfo;

/// # Safety
///
/// `TaskInfo` is the right size to be passed to `proc_pidinfo`.
#[cfg(target_os = "macos")]
impl PIDInfo for TaskInfo {
unsafe impl PIDInfo for TaskInfo {
fn flavor() -> PidInfoFlavor {
PidInfoFlavor::TaskInfo
}
Expand All @@ -21,8 +24,11 @@ pub struct TaskAllInfo {
pub ptinfo: TaskInfo,
}

/// # Safety
///
/// `TaskInfoAll` is the right size to be passed to `proc_pidinfo`.
#[cfg(target_os = "macos")]
impl PIDInfo for TaskAllInfo {
unsafe impl PIDInfo for TaskAllInfo {
fn flavor() -> PidInfoFlavor {
PidInfoFlavor::TaskAllInfo
}
Expand Down
5 changes: 4 additions & 1 deletion src/libproc/thread_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,11 @@ use crate::libproc::proc_pid::{PIDInfo, PidInfoFlavor};
#[cfg(target_os = "macos")]
pub use crate::osx_libproc_bindings::proc_threadinfo as ThreadInfo;

/// # Safety
///
/// `ThreadInfo` is the right size to be passed to `proc_pidinfo`.
#[cfg(target_os = "macos")]
impl PIDInfo for ThreadInfo {
unsafe impl PIDInfo for ThreadInfo {
fn flavor() -> PidInfoFlavor {
PidInfoFlavor::ThreadInfo
}
Expand Down
5 changes: 4 additions & 1 deletion src/libproc/work_queue_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@ pub struct WorkQueueInfo {
pub reserved: [u32; 1],
}

impl PIDInfo for WorkQueueInfo {
/// # Safety
///
/// `WorkQueueInfo` is the right size to be passed to `proc_pidinfo`.
unsafe impl PIDInfo for WorkQueueInfo {
fn flavor() -> PidInfoFlavor {
PidInfoFlavor::WorkQueueInfo
}
Expand Down

0 comments on commit 3e42c03

Please sign in to comment.