Skip to content

Commit 78b7e6f

Browse files
committed
Make *::from_anything methods unsafe
The called function must uphold some invariants about initializing data in order for the calls to `from_anything` to be sound.
1 parent 15d624a commit 78b7e6f

File tree

1 file changed

+40
-14
lines changed

1 file changed

+40
-14
lines changed

src/unistd.rs

Lines changed: 40 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3631,7 +3631,12 @@ impl From<User> for libc::passwd {
36313631

36323632
#[cfg(not(target_os = "redox"))] // RedoxFS does not support passwd
36333633
impl User {
3634-
fn from_anything<F>(f: F) -> Result<Option<Self>>
3634+
/// # Safety
3635+
///
3636+
/// If `f` writes to its `*mut *mut libc::passwd` parameter, then it must
3637+
/// also initialize the value pointed to by its `*mut libc::group`
3638+
/// parameter.
3639+
unsafe fn from_anything<F>(f: F) -> Result<Option<Self>>
36353640
where
36363641
F: Fn(
36373642
*mut libc::passwd,
@@ -3687,9 +3692,13 @@ impl User {
36873692
/// assert_eq!(res.name, "root");
36883693
/// ```
36893694
pub fn from_uid(uid: Uid) -> Result<Option<Self>> {
3690-
User::from_anything(|pwd, cbuf, cap, res| unsafe {
3691-
libc::getpwuid_r(uid.0, pwd, cbuf, cap, res)
3692-
})
3695+
// SAFETY: `getpwuid_r` will write to `res` if it initializes the value
3696+
// at `pwd`.
3697+
unsafe {
3698+
User::from_anything(|pwd, cbuf, cap, res| {
3699+
libc::getpwuid_r(uid.0, pwd, cbuf, cap, res)
3700+
})
3701+
}
36933702
}
36943703

36953704
/// Get a user by name.
@@ -3710,9 +3719,13 @@ impl User {
37103719
Ok(c_str) => c_str,
37113720
Err(_nul_error) => return Ok(None),
37123721
};
3713-
User::from_anything(|pwd, cbuf, cap, res| unsafe {
3714-
libc::getpwnam_r(name.as_ptr(), pwd, cbuf, cap, res)
3715-
})
3722+
// SAFETY: `getpwnam_r` will write to `res` if it initializes the value
3723+
// at `pwd`.
3724+
unsafe {
3725+
User::from_anything(|pwd, cbuf, cap, res| {
3726+
libc::getpwnam_r(name.as_ptr(), pwd, cbuf, cap, res)
3727+
})
3728+
}
37163729
}
37173730
}
37183731

@@ -3763,7 +3776,12 @@ impl Group {
37633776
ret
37643777
}
37653778

3766-
fn from_anything<F>(f: F) -> Result<Option<Self>>
3779+
/// # Safety
3780+
///
3781+
/// If `f` writes to its `*mut *mut libc::group` parameter, then it must
3782+
/// also initialize the value pointed to by its `*mut libc::group`
3783+
/// parameter.
3784+
unsafe fn from_anything<F>(f: F) -> Result<Option<Self>>
37673785
where
37683786
F: Fn(
37693787
*mut libc::group,
@@ -3821,9 +3839,13 @@ impl Group {
38213839
/// assert!(res.name == "root");
38223840
/// ```
38233841
pub fn from_gid(gid: Gid) -> Result<Option<Self>> {
3824-
Group::from_anything(|grp, cbuf, cap, res| unsafe {
3825-
libc::getgrgid_r(gid.0, grp, cbuf, cap, res)
3826-
})
3842+
// SAFETY: `getgrgid_r` will write to `res` if it initializes the value
3843+
// at `grp`.
3844+
unsafe {
3845+
Group::from_anything(|grp, cbuf, cap, res| {
3846+
libc::getgrgid_r(gid.0, grp, cbuf, cap, res)
3847+
})
3848+
}
38273849
}
38283850

38293851
/// Get a group by name.
@@ -3846,9 +3868,13 @@ impl Group {
38463868
Ok(c_str) => c_str,
38473869
Err(_nul_error) => return Ok(None),
38483870
};
3849-
Group::from_anything(|grp, cbuf, cap, res| unsafe {
3850-
libc::getgrnam_r(name.as_ptr(), grp, cbuf, cap, res)
3851-
})
3871+
// SAFETY: `getgrnam_r` will write to `res` if it initializes the value
3872+
// at `grp`.
3873+
unsafe {
3874+
Group::from_anything(|grp, cbuf, cap, res| {
3875+
libc::getgrnam_r(name.as_ptr(), grp, cbuf, cap, res)
3876+
})
3877+
}
38523878
}
38533879
}
38543880
}

0 commit comments

Comments
 (0)