|
| 1 | +use crate::Result; |
| 2 | +use crate::errno::Errno; |
| 3 | + |
| 4 | +use libc::{self, c_int, c_ulong}; |
| 5 | + |
| 6 | +libc_bitflags! { |
| 7 | + /// Flags used and returned by [`get()`](fn.get.html) and |
| 8 | + /// [`set()`](fn.set.html). |
| 9 | + pub struct Persona: c_int { |
| 10 | + ADDR_COMPAT_LAYOUT; |
| 11 | + ADDR_NO_RANDOMIZE; |
| 12 | + ADDR_LIMIT_32BIT; |
| 13 | + ADDR_LIMIT_3GB; |
| 14 | + #[cfg(not(target_env = "musl"))] |
| 15 | + FDPIC_FUNCPTRS; |
| 16 | + MMAP_PAGE_ZERO; |
| 17 | + READ_IMPLIES_EXEC; |
| 18 | + SHORT_INODE; |
| 19 | + STICKY_TIMEOUTS; |
| 20 | + #[cfg(not(target_env = "musl"))] |
| 21 | + UNAME26; |
| 22 | + WHOLE_SECONDS; |
| 23 | + } |
| 24 | +} |
| 25 | + |
| 26 | +/// Retrieve the current process personality. |
| 27 | +/// |
| 28 | +/// Returns a Result containing a Persona instance. |
| 29 | +/// |
| 30 | +/// Example: |
| 31 | +/// |
| 32 | +/// ``` |
| 33 | +/// # use nix::sys::personality::{self, Persona}; |
| 34 | +/// let pers = personality::get().unwrap(); |
| 35 | +/// assert!(!pers.contains(Persona::WHOLE_SECONDS)); |
| 36 | +/// ``` |
| 37 | +pub fn get() -> Result<Persona> { |
| 38 | + let res = unsafe { |
| 39 | + libc::personality(0xFFFFFFFF) |
| 40 | + }; |
| 41 | + |
| 42 | + Errno::result(res).map(|r| Persona::from_bits_truncate(r)) |
| 43 | +} |
| 44 | + |
| 45 | +/// Set the current process personality. |
| 46 | +/// |
| 47 | +/// Returns a Result containing the *previous* personality for the |
| 48 | +/// process, as a Persona. |
| 49 | +/// |
| 50 | +/// For more information, see [personality(2)](https://man7.org/linux/man-pages/man2/personality.2.html) |
| 51 | +/// |
| 52 | +/// **NOTE**: This call **replaces** the current personality entirely. |
| 53 | +/// To **update** the personality, first call `get()` and then `set()` |
| 54 | +/// with the modified persona. |
| 55 | +/// |
| 56 | +/// Example: |
| 57 | +/// |
| 58 | +/// ``` |
| 59 | +/// # use nix::sys::personality::{self, Persona}; |
| 60 | +/// let mut pers = personality::get().unwrap(); |
| 61 | +/// assert!(!pers.contains(Persona::ADDR_NO_RANDOMIZE)); |
| 62 | +/// personality::set(pers | Persona::ADDR_NO_RANDOMIZE); |
| 63 | +/// ``` |
| 64 | +pub fn set(persona: Persona) -> Result<Persona> { |
| 65 | + let res = unsafe { |
| 66 | + libc::personality(persona.bits() as c_ulong) |
| 67 | + }; |
| 68 | + |
| 69 | + Errno::result(res).map(|r| Persona::from_bits_truncate(r)) |
| 70 | +} |
0 commit comments