Skip to content

usize as c_int is not a conversion that is guaranteed to be correct #2668

@zacknewman

Description

@zacknewman

I haven't looked much in the crate, but there is at least one case where usize as c_int is being used. Seeing how c_int is normally an i32 but is technically any signed integer at least the size of c_short, shouldn't c_int::try_from be used instead? For example, unistd::setgroups:

#[cfg(not(any(
    apple_targets,
    target_os = "redox",
    target_os = "haiku"
)))]
pub fn setgroups(groups: &[Gid]) -> Result<()> {
    cfg_if! {
        if #[cfg(any(bsd,
                     solarish,
                     target_os = "aix",
                     target_os = "cygwin"))] {
            type setgroups_ngroups_t = c_int;
        } else {
            type setgroups_ngroups_t = size_t;
        }
    }
    // FIXME: On the platforms we currently support, the `Gid` struct has the
    // same representation in memory as a bare `gid_t`. This is not necessarily
    // the case on all Rust platforms, though. See RFC 1785.
    let res = unsafe {
        libc::setgroups(
            groups.len() as setgroups_ngroups_t,
            groups.as_ptr().cast(),
        )
    };

    Errno::result(res).map(drop)
}

When setgroups_ngroups_t is c_int, groups.len() as setgroups_ngroups_t may produce the wrong result. I'm sure this is unlikely, but it is technically possible.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions