unix_is_elevated/
lib.rs

1//! Check whether the running process has elevated privileges, under Unix.
2//!
3//! The [`is_elevated`] function uses:
4//!
5//! - `getauxval(AT_SECURE)` on Linux, if available,
6//! - `issetugid()` on MacOS and *BSD,
7//! - `getuid() != geteuid() || getgid() != getegid()` as fallback.
8
9#[cfg(target_os = "linux")]
10pub fn is_elevated() -> bool {
11    // SAFETY: No safety preconditions to call `getauxval`.
12    let res = unsafe { libc::getauxval(libc::AT_SECURE) };
13
14    if res > 0 {
15        return true;
16    }
17
18    if res == 0 && Error::last_os_error().kind() != ErrorKind::InvalidInput {
19        return false;
20    }
21
22    is_posix_elevated()
23}
24
25#[cfg(any(
26    target_os = "macos",
27    target_os = "freebsd",
28    target_os = "dragonfly",
29    target_os = "openbsd",
30    target_os = "netbsd"))]
31pub fn is_elevated() -> bool {
32    unsafe extern "C" {
33        unsafe fn issetugid() -> libc::c_int;
34    }
35
36    // SAFETY: No safety preconditions to call `issetugid`.
37    return unsafe { issetugid() != 0 };
38}
39
40#[cfg(not(any(
41    target_os = "linux",
42    target_os = "macos",
43    target_os = "freebsd",
44    target_os = "dragonfly",
45    target_os = "openbsd",
46    target_os = "netbsd")))]
47pub fn is_elevated() -> bool {
48    is_posix_elevated()
49}
50
51fn is_posix_elevated() -> bool {
52    // SAFETY: No safety preconditions to call `getuid`, `geteuid`, `getgid`, and `getegid`.
53    unsafe {
54        libc::getuid() != libc::geteuid() || libc::getgid() != libc::getegid()
55    }
56}
57
58/// Returns whether the process is running as root (uid 0).
59pub fn is_root() -> bool {
60    // SAFETY: No safety preconditions to call `getuid` and `geteuid`.
61    unsafe { libc::getuid() == 0 || libc::geteuid() == 0 }
62}
63
64use std::io::{Error, ErrorKind};